cannot find object instance
Bruno Desthuilliers
bruno.42.desthuilliers at websiteburo.invalid
Thu Aug 28 12:35:42 EDT 2008
jimgardener a écrit :
> hi,
> i am a python newbie..
From what I can see from your code, you're a newbie to programming in
general...
> while trying out some message passing between
> two object instances i came across a problem
First point : you have both a circular dependency between ModuleA and
ModuleB - which is better to avoid unless you really like headaches...
You mention Java somewhere else, so I assume you have some at least some
Java background. Point here is that Python is not Java, and doesn't
restrict you to one ("public") class per module. IOW, if you have two
strongly related classes (which is obviously the case here), better to
put both in a same module.
> moduleA.py
> --------------------
> import moduleB
> class MyClassA:
> def __init__(self):
> self.age=0
> self.address=''
> def createClassB(self):
> self.objB=moduleB.MyClassB()
Why is this in a distinct method instead of being in the initializer ?
And why is it named create*Class* when it creates an *instance* ?
> def validate(self,age,address):
> if(age >= 100 or address==''):
> self.age=20;
> self.address="Broadway,NewYork"
> self.objB.display(self.age,self.address)
> def callB(self):
> self.objB.execute()
Looks like a somewhat messy, circonvoluted and arbitrary
overcomplexificated control flow...
> if __name__ == "__main__":
> objA=MyClassA()
> objA.createClassB()
> objA.callB()
>
> moduleB.py
> ------------------
> import moduleA
>
> class MyClassB:
> def __init__(self):
> self.createA()
> def createA(self):
> self.objA=moduleA.MyClassA()
You do understand that self.objA won't be the same MyClassA instance as
the one that instanciated this instance of MyClassB, do you ?
> def execute(self):
> self.objA.validate(111,'')
> def display(self,age,address):
> print 'displaying:',str(age),address
You don't have to call str on age here.
>
> when i run the code i get a message
> AttributeError: MyClassA instance has no attribute 'objB'
Indeed.
You first create an instance of MyClassA named objA, call createClassB()
on it which create an instance of MyClassB referenced by objA.objB.
When objA.objB is created, it itself creates another instance of
MyClassA referenced by objA.objB.objA, which is totally distinct from
objA...
Then you call objA.callB(),
which itself call objA.objB.execute(),
which in turn call objA.objB.objA.validate(),
which in turn call objA.objB.objA.objB.display().
But at this point, objA.objB.objA (which, I repeat, is *not* objA) has
no attribute objB since you didn't call objA.objB.objA.createClassB()...
You could have understood this by yourself, either the way I did
(mentally tracing program execution) or using a couple print statements
in your code (to effectively trace program execution), or using the
debugger...
> Do i have to put a placeholder for objB in __init__ of MyClassA ?
> is that why i get this error?someone please tell me how i can solve
> this? I tried to put self.objB=None but it didn't work..
<ot>
Trying anything that comes to mind instead of trying to understand how
things work is a well-known antipattern named "programming by accident".
The best you can hope from this approach is that, for unknown reasons,
things accidentally seem to work. Until the day where, for still unknown
reasons, they either stop working, or it appears they never really
worked at all.
Needless to say, this approach is a pure waste of time.
</ot>
class ClassA(object):
def __init__(self, age=0, address=''):
self.age = age
self.address = address
self.b= ClassB(self)
def validate(self,age,address):
if(age >= 100 or address==''):
self.age=20;
self.address="Broadway,NewYork"
self.b.display(self.age, self.address)
def call_b(self):
self.b.execute()
class ClassB(object):
def __init__(self, a):
self.a = a
def execute(self):
self.a.validate(111,'')
def display(self, age, address):
print 'displaying: %s %s' % (age, address)
if __name__ == "__main__":
objA=ClassA()
objA.call_b()
Note that this is still uselessly messy and arbitrary
overcomplificated... Such a ping-pong between two classes is more often
than not a design smell.
HTH
More information about the Python-list
mailing list