Re: Inheritance and forward references (prototypes)

2009-06-22 Thread Lorenzo Di Gregorio
On 21 Jun., 22:51, Scott David Daniels scott.dani...@acm.org wrote:
 LorenzoDiGregoriowrote:
  On 21 Jun., 01:54, Dave Angel da...@ieee.org wrote:
  ...
  class B(object):
      def __init__(self,test=None):
          if test==None:
              test = A()
          self.obj =()
          return
  ...
  I had also thought of using None (or whatever else) as a marker but
  I was curious to find out whether there are better ways to supply an
  object with standard values as a default argument.
  In this sense, I was looking for problems ;-)

  Of course the observation that def is an instruction and no
  declaration changes the situation: I would not have a new object being
  constructed for every instantiation with no optional argument, because
  __init__ gets executed on the instantiation but test=A() gets executed
  on reading 'def'

 If what you are worrying about is having a single default object, you
 could do something like this:

      class B(object):
          _default = None

          def __init__(self, test=None):
              if test is None:
                  test = self._default
                  if test is None:
                      B._default = test = A()
              ...

 --Scott David Daniels
 scott.dani...@acm.org- Zitierten Text ausblenden -

 - Zitierten Text anzeigen -

Well, I could also declare (ups, define ;-)) __init__(self,**kwargs)
and within the __init__, if kwargs['test'] exists, do test = kwargs
['test'], if it does not exist, do test = A().

The point is that it would have been cleaner to place it straight in
the __init__, but due to the semantic of 'def' this does not seem
possible.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Inheritance and forward references (prototypes)

2009-06-21 Thread Lorenzo Di Gregorio
On 21 Jun., 01:54, Dave Angel da...@ieee.org wrote:
 LorenzoDiGregoriowrote:
  On Jun 20, 8:43 pm, Dave Angel da...@ieee.org wrote:

 LorenzoDiGregoriowrote:

  Hi,

  I'm wondering what would be the preferred way to solve the following
  forward reference problem:

  ---
  class BaseA(object):
      def __init__(self):
          return

  class DebugA(BaseA):
      def __init__(self):
          return

  # here I would have a prototype of class A which is the same as class
  BaseA

  class B(object):
      def __init__(self):
          self.obj =()
          return

  if __name__ =__main__:
  #    class A(BaseA): # Uncomment this for using BaseA objects
  #       pass
      class A(DebugA): # Uncomment this for using DebugA objects
          pass
  ---

  I can figure out some ways to fix this but none seems satisfying.
  Either they are too specific or too cumbersome.
  A runtime redefinition of class A does not seem to work either.
  What would be the most pythonesque solution other than sorting out
  the class order?

  Best Regards,
 Lorenzo

  You haven't shown us any problem.  class B works fine with a forward
  reference to A.  Now if you were trying to subclass A before defining
  it, that'd be a problem.  Or if you were trying to make an instance of B
  before defining A.

  Better put some code together with enough meat to actually show a
  symptom.  And tell us what sys.version says.  I'm testing with   2.6.2
  (r262:71605, Apr 14 2009, 22:40:02) [MSC v.1500 32 bit (Intel)], running
  on Win XP.- Hide quoted text -

  - Show quoted text -

  Thank you for your help: I'm working on a rather large source, but I
  think I have isolated the problem now.
  This listing generates an error:

  ---
  class BaseA(object):
      def __init__(self):
          return

  class DebugA(BaseA):
      def __init__(self):
          return

  class B(object):
      def __init__(self,test=A()):
          self.obj =()
          return

  if __name__ =__main__:
  #    class A(BaseA): # Uncomment this for using BaseA objects
  #        pass
       class A(DebugA): # Uncomment this for using DebugA objects
           pass
  ---

  The error happens because Python apparently evaluates the named
  arguments before running the script.
  I think I have read something about this some (long) time ago but I
  can't find it anymore.

  Suggestions?

  BTW, my Python version is 2.6.1 (with latest PyDev).

  Thx!
 Lorenzo

 This error is caused because a default argument uses class A.  Default
 arguments of class methods are evaluated during the definition of the
 class, and not later when the class is instantiated.  Thus the problem.

 To work around that specific problem, you may want to use the following:

 class B(object):
     def __init__(self,test=None):
         if test==None:
             test = A()
         self.obj =()
         return

 This is actually different than what you had, since what you had would
 have used the same A() object for all instances of B that didn't supply
 their own test() parameter.  Maybe that's what you wanted, and maybe
 not, but default arguments set to mutable values are frequently a bug.

 But I'm wondering if you're just looking for problems.  Why not put the
 commented switch early in the file, and test for it wherever you need to
 use it?

 import  x, y, z
 _debug = False
 #_debug = True

 then as soon as  BaseA and DebugA are defined, do the following:

 if _debug:
     class A(DebugA):
         pass
 else:
     class A(BaseA)
         pass- Zitierten Text ausblenden -

 - Zitierten Text anzeigen -

I had also thought of using None (or whatever else) as a marker but
I was curious to find out whether there are better ways to supply an
object with standard values as a default argument.
In this sense, I was looking for problems ;-)

Of course the observation that def is an instruction and no
declaration changes the situation: I would not have a new object being
constructed for every instantiation with no optional argument, because
__init__ gets executed on the instantiation but test=A() gets executed
on reading 'def'.

At this point I think there is no other way than using a marker as
suggested above multiple times, if I want to supply a new object with
default values for non-passed arguments.

Anybody with a better idea?
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Inheritance and forward references (prototypes)

2009-06-21 Thread Lie Ryan
Lorenzo Di Gregorio wrote:
 I had also thought of using None (or whatever else) as a marker but
 I was curious to find out whether there are better ways to supply an
 object with standard values as a default argument.
 In this sense, I was looking for problems ;-)
 
 Of course the observation that def is an instruction and no
 declaration changes the situation: I would not have a new object being
 constructed for every instantiation with no optional argument, because
 __init__ gets executed on the instantiation but test=A() gets executed
 on reading 'def'.
 
 At this point I think there is no other way than using a marker as
 suggested above multiple times, if I want to supply a new object with
 default values for non-passed arguments.

Using None as default for mutable default argument is the common idiom
for the problem you're having.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Inheritance and forward references (prototypes)

2009-06-21 Thread Scott David Daniels

Lorenzo Di Gregorio wrote:

On 21 Jun., 01:54, Dave Angel da...@ieee.org wrote:

...
class B(object):
def __init__(self,test=None):
if test==None:
test = A()
self.obj =()
return

...
I had also thought of using None (or whatever else) as a marker but
I was curious to find out whether there are better ways to supply an
object with standard values as a default argument.
In this sense, I was looking for problems ;-)

Of course the observation that def is an instruction and no
declaration changes the situation: I would not have a new object being
constructed for every instantiation with no optional argument, because
__init__ gets executed on the instantiation but test=A() gets executed
on reading 'def'


If what you are worrying about is having a single default object, you
could do something like this:

class B(object):
_default = None

def __init__(self, test=None):
if test is None:
test = self._default
if test is None:
B._default = test = A()
...


--Scott David Daniels
scott.dani...@acm.org
--
http://mail.python.org/mailman/listinfo/python-list


Inheritance and forward references (prototypes)

2009-06-20 Thread Lorenzo Di Gregorio
Hi,

I'm wondering what would be the preferred way to solve the following
forward reference problem:

---
class BaseA(object):
def __init__(self):
return

class DebugA(BaseA):
def __init__(self):
return

# here I would have a prototype of class A which is the same as class
BaseA

class B(object):
def __init__(self):
self.obj = A()
return

if __name__ == __main__:
#class A(BaseA): # Uncomment this for using BaseA objects
#   pass
class A(DebugA): # Uncomment this for using DebugA objects
pass
---

I can figure out some ways to fix this but none seems satisfying.
Either they are too specific or too cumbersome.
A runtime redefinition of class A does not seem to work either.
What would be the most pythonesque solution other than sorting out
the class order?

Best Regards,
Lorenzo
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Inheritance and forward references (prototypes)

2009-06-20 Thread Steven D'Aprano
Lorenzo Di Gregorio wrote:

 Hi,
 
 I'm wondering what would be the preferred way to solve the following
 forward reference problem:

You don't actually explain what is the problem. Fortunately, I'm good at
guessing, and I think I can guess what your problem is (see below):


 ---
 class BaseA(object):
 def __init__(self):
 return
 
 class DebugA(BaseA):
 def __init__(self):
 return
 
 # here I would have a prototype of class A which is the same as class
 BaseA
 
 class B(object):
 def __init__(self):
 self.obj = A()
 return
 
 if __name__ == __main__:
 #class A(BaseA): # Uncomment this for using BaseA objects
 #   pass
 class A(DebugA): # Uncomment this for using DebugA objects
 pass
 ---

Class A only gets defined if you run the module as a script. What you need
is to unconditionally define class A, outside of the if __name__ block:


class A(BaseA):
pass

# A.__base__ = DebugA  ## Uncomment this line for debugging.




-- 
Steven

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Inheritance and forward references (prototypes)

2009-06-20 Thread Dave Angel

Lorenzo Di Gregorio wrote:

Hi,

I'm wondering what would be the preferred way to solve the following
forward reference problem:

---
class BaseA(object):
def __init__(self):
return

class DebugA(BaseA):
def __init__(self):
return

# here I would have a prototype of class A which is the same as class
BaseA

class B(object):
def __init__(self):
self.obj = A()
return

if __name__ == __main__:
#class A(BaseA): # Uncomment this for using BaseA objects
#   pass
class A(DebugA): # Uncomment this for using DebugA objects
pass
---

I can figure out some ways to fix this but none seems satisfying.
Either they are too specific or too cumbersome.
A runtime redefinition of class A does not seem to work either.
What would be the most pythonesque solution other than sorting out
the class order?

Best Regards,
Lorenzo

  
You haven't shown us any problem.  class B works fine with a forward 
reference to A.  Now if you were trying to subclass A before defining 
it, that'd be a problem.  Or if you were trying to make an instance of B 
before defining A.


Better put some code together with enough meat to actually show a 
symptom.  And tell us what sys.version says.  I'm testing with   2.6.2 
(r262:71605, Apr 14 2009, 22:40:02) [MSC v.1500 32 bit (Intel)], running 
on Win XP.



--
http://mail.python.org/mailman/listinfo/python-list


Re: Inheritance and forward references (prototypes)

2009-06-20 Thread Piet van Oostrum
 Steven D'Aprano st...@removethis.cybersource.com.au (SD) wrote:

SD Lorenzo Di Gregorio wrote:
 Hi,
 
 I'm wondering what would be the preferred way to solve the following
 forward reference problem:

SD You don't actually explain what is the problem. Fortunately, I'm good at
SD guessing, and I think I can guess what your problem is (see below):


 ---
 class BaseA(object):
 def __init__(self):
 return
 
 class DebugA(BaseA):
 def __init__(self):
 return
 
 # here I would have a prototype of class A which is the same as class
 BaseA
 
 class B(object):
 def __init__(self):
 self.obj = A()
 return
 
 if __name__ == __main__:
 #class A(BaseA): # Uncomment this for using BaseA objects
 #   pass
 class A(DebugA): # Uncomment this for using DebugA objects
 pass
 ---

SD Class A only gets defined if you run the module as a script. What you need
SD is to unconditionally define class A, outside of the if __name__ block:


SD class A(BaseA):
SD pass

SD # A.__base__ = DebugA  ## Uncomment this line for debugging.

A.__base__ = DebugA
TypeError: readonly attribute

Make that: A.__bases__ = DebugA,

SD -- 
SD Steven


-- 
Piet van Oostrum p...@cs.uu.nl
URL: http://pietvanoostrum.com [PGP 8DAE142BE17999C4]
Private email: p...@vanoostrum.org
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Inheritance and forward references (prototypes)

2009-06-20 Thread Lorenzo Di Gregorio
On Jun 20, 8:43 pm, Dave Angel da...@ieee.org wrote:
 Lorenzo Di Gregorio wrote:
  Hi,

  I'm wondering what would be the preferred way to solve the following
  forward reference problem:

  ---
  class BaseA(object):
      def __init__(self):
          return

  class DebugA(BaseA):
      def __init__(self):
          return

  # here I would have a prototype of class A which is the same as class
  BaseA

  class B(object):
      def __init__(self):
          self.obj = A()
          return

  if __name__ == __main__:
  #    class A(BaseA): # Uncomment this for using BaseA objects
  #       pass
      class A(DebugA): # Uncomment this for using DebugA objects
          pass
  ---

  I can figure out some ways to fix this but none seems satisfying.
  Either they are too specific or too cumbersome.
  A runtime redefinition of class A does not seem to work either.
  What would be the most pythonesque solution other than sorting out
  the class order?

  Best Regards,
  Lorenzo

 You haven't shown us any problem.  class B works fine with a forward
 reference to A.  Now if you were trying to subclass A before defining
 it, that'd be a problem.  Or if you were trying to make an instance of B
 before defining A.

 Better put some code together with enough meat to actually show a
 symptom.  And tell us what sys.version says.  I'm testing with   2.6.2
 (r262:71605, Apr 14 2009, 22:40:02) [MSC v.1500 32 bit (Intel)], running
 on Win XP.- Hide quoted text -

 - Show quoted text -

Thank you for your help: I'm working on a rather large source, but I
think I have isolated the problem now.
This listing generates an error:

---
class BaseA(object):
def __init__(self):
return

class DebugA(BaseA):
def __init__(self):
return

class B(object):
def __init__(self,test=A()):
self.obj = A()
return

if __name__ == __main__:
#class A(BaseA): # Uncomment this for using BaseA objects
#pass
 class A(DebugA): # Uncomment this for using DebugA objects
 pass
---

The error happens because Python apparently evaluates the named
arguments before running the script.
I think I have read something about this some (long) time ago but I
can't find it anymore.

Suggestions?

BTW, my Python version is 2.6.1 (with latest PyDev).

Thx!
Lorenzo
-- 
http://mail.python.org/mailman/listinfo/python-list


Inheritance and forward references (prototypes)

2009-06-20 Thread Xavier Ho
Arg, forgot to post to the mailing list again. -_-

On a smaller issue, don't you need to do:

class DebugA(BaseA):
def __init__(self):
BaseA.__init__(self)
return

As in, explicitly call the __init__ function when you initalise DebugA,
since DebugA extends BaseA?

I'm just getting this necessary step because my books say so. If anyone
has a good explanation, please do tell.

Best regards,

Ching-Yun Xavier Ho, Technical Artist

Contact Information
Mobile: (+61) 04 3335 4748
Skype ID: SpaXe85
Email: cont...@xavierho.com
Website: http://xavierho.com/



On Sun, Jun 21, 2009 at 6:26 AM, Lorenzo Di Gregorio 
lorenzo.digrego...@gmail.com wrote:

 On Jun 20, 8:43 pm, Dave Angel da...@ieee.org wrote:
  Lorenzo Di Gregorio wrote:
   Hi,
 
   I'm wondering what would be the preferred way to solve the following
   forward reference problem:
 
   ---
   class BaseA(object):
   def __init__(self):
   return
 
   class DebugA(BaseA):
   def __init__(self):
   return
 
   # here I would have a prototype of class A which is the same as class
   BaseA
 
   class B(object):
   def __init__(self):
   self.obj = A()
   return
 
   if __name__ == __main__:
   #class A(BaseA): # Uncomment this for using BaseA objects
   #   pass
   class A(DebugA): # Uncomment this for using DebugA objects
   pass
   ---
 
   I can figure out some ways to fix this but none seems satisfying.
   Either they are too specific or too cumbersome.
   A runtime redefinition of class A does not seem to work either.
   What would be the most pythonesque solution other than sorting out
   the class order?
 
   Best Regards,
   Lorenzo
 
  You haven't shown us any problem.  class B works fine with a forward
  reference to A.  Now if you were trying to subclass A before defining
  it, that'd be a problem.  Or if you were trying to make an instance of B
  before defining A.
 
  Better put some code together with enough meat to actually show a
  symptom.  And tell us what sys.version says.  I'm testing with   2.6.2
  (r262:71605, Apr 14 2009, 22:40:02) [MSC v.1500 32 bit (Intel)], running
  on Win XP.- Hide quoted text -
 
  - Show quoted text -

 Thank you for your help: I'm working on a rather large source, but I
 think I have isolated the problem now.
 This listing generates an error:

 ---
 class BaseA(object):
def __init__(self):
return

 class DebugA(BaseA):
def __init__(self):
return

 class B(object):
def __init__(self,test=A()):
 self.obj = A()
return

 if __name__ == __main__:
 #class A(BaseA): # Uncomment this for using BaseA objects
 #pass
 class A(DebugA): # Uncomment this for using DebugA objects
 pass
 ---

 The error happens because Python apparently evaluates the named
 arguments before running the script.
 I think I have read something about this some (long) time ago but I
 can't find it anymore.

 Suggestions?

 BTW, my Python version is 2.6.1 (with latest PyDev).

 Thx!
 Lorenzo
 --
 http://mail.python.org/mailman/listinfo/python-list

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Inheritance and forward references (prototypes)

2009-06-20 Thread Rhodri James
On Sat, 20 Jun 2009 21:26:56 +0100, Lorenzo Di Gregorio  
lorenzo.digrego...@gmail.com wrote:



Thank you for your help: I'm working on a rather large source, but I
think I have isolated the problem now.
This listing generates an error:

---
class BaseA(object):
def __init__(self):
return

class DebugA(BaseA):
def __init__(self):
return

class B(object):
def __init__(self,test=A()):
self.obj = A()
return

if __name__ == __main__:
#class A(BaseA): # Uncomment this for using BaseA objects
#pass
 class A(DebugA): # Uncomment this for using DebugA objects
 pass
---

The error happens because Python apparently evaluates the named
arguments before running the script.
I think I have read something about this some (long) time ago but I
can't find it anymore.


I could have sworn this was in the FAQ, but apparently not.  You're
right, Python evaluates the default arguments when it executes the
`def` instruction.  (Yes, `def` is an executable instruction.  It's
got to create the function/method object after all!)

The usual fix is not to make the default an instance of A (which
will have all sorts of other side effects as well, since the same
instance of A will be shared by all the Bs that don't supply a
`test` parameter), but to use `None` as a marker.

class B(object):
def __init__(self, test=None):
if test is None:
test = A()
self.obj = A()

and so on.
--
Rhodri James *-* Wildebeest Herder to the Masses
--
http://mail.python.org/mailman/listinfo/python-list