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
--
http://mail.python.org/mailman/listinfo/python-list

Reply via email to