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