object knows which object called it?

R

Reckoner

hi,

I have the following problem: I have two objects, say, A and B, which
are both legitimate stand-alone objects with lives of their own.

A contains B as a property, so I often do

A.B.foo()

the problem is that some functions inside of B actually need A
(remember I said they were both standalone objects), so I have to
often do:

A.B.foo_func(A)

Which is kind of awkward.

Is there some way that B.foo_func() could somehow know that it was
called as a property of A in this way?

Note that I'm looking for the calling object and NOT the calling
function.

Thanks in advance.
 
D

Dennis Lee Bieber

Is there some way that B.foo_func() could somehow know that it was
called as a property of A in this way?

Note that I'm looking for the calling object and NOT the calling
function.
Not really...

class A(object):
pass

class B(object):
pass

A1 = A()
A2 = A()
B = B()

A1.b = B
A2.b = B

A1.b.confused()
Which is the "owner"... .b in both A instances access the same
single B instance -- id(A1.b) == id(A2.b).

Examining the calling stack MIGHT get you to the specific instance
but that's an esoteric technique I've never used, and hence can't point
to the specific function calls needed.
Thanks in advance.
--
Wulfraed Dennis Lee Bieber KD6MOG
(e-mail address removed) (e-mail address removed)
HTTP://wlfraed.home.netcom.com/
(Bestiaria Support Staff: (e-mail address removed))
HTTP://www.bestiaria.com/
 
R

R. David Murray

Reckoner said:
hi,

I have the following problem: I have two objects, say, A and B, which
are both legitimate stand-alone objects with lives of their own.

A contains B as a property, so I often do

A.B.foo()

the problem is that some functions inside of B actually need A
(remember I said they were both standalone objects), so I have to
often do:

A.B.foo_func(A)

Which is kind of awkward.

Is there some way that B.foo_func() could somehow know that it was
called as a property of A in this way?

Note that I'm looking for the calling object and NOT the calling
function.

You could probably do this by creating a custom __getattr__ method (or
maybe even just a property) on A that would recognize B as an object and
return it wrapped in a class that would pick up the __getattr__ call on B
and translate it into a real call on B passing A as the first argument.

But that kind of magic is not considered good Python practice ("explicit
is better than implicit"). And it would be quite inefficient :)

I think the OO way to do this is to provide a method on A that does the
right thing:

def Bfoo_func(self):
self.B.foo_func(self)

Or maybe you could look at generic methods, which provide a way
to do multiple dispatch.
 
A

Aaron Brady

hi,

I have the following problem: I have two objects, say, A and B, which
are both legitimate stand-alone objects with lives of their own.

A contains B as a property, so I often do

A.B.foo()

the problem is that some functions inside of B actually need A
(remember I said they were both standalone objects), so I have to
often do:

A.B.foo_func(A)

Which is kind of awkward.

Is there some way that B.foo_func() could somehow know that it was
called as a property of A in this way?

Note that I'm looking for the calling object and NOT the calling
function.

Thanks in advance.

Hi Reckoner,

I believe this does what you want. It's an advanced technique and not
available in all OO languages.

class ClsA( object ):
def __init__( self ):
self.inst= None
def __get__( self, instance, owner ):
self.inst= instance
return self
def submethA( self, arg ):
print( 'submethA %r, instance %r'% ( arg, self.inst ) )

class ClsB( object ):
A= ClsA( )
def methA( self, arg ):
print( 'methA %r'% arg )

b= ClsB( )
b.methA( 'this' )
b.A.submethA( 'that' )

#Output:
'''
methA 'this'
submethA 'that', instance <__main__.ClsB object...>
'''

There's a small discussion in another today's thread, 'group several
methods under an attribute'.
 
A

Anthra Norell

Reckoner said:
hi,

I have the following problem: I have two objects, say, A and B, which
are both legitimate stand-alone objects with lives of their own.

A contains B as a property, so I often do

A.B.foo()

the problem is that some functions inside of B actually need A
(remember I said they were both standalone objects), so I have to
often do:

A.B.foo_func(A)

Which is kind of awkward.

Is there some way that B.foo_func() could somehow know that it was
called as a property of A in this way?

Note that I'm looking for the calling object and NOT the calling
function.

Thanks in advance.

B has to get into A somehow. Providing an installation method is no
inconvenience if one remembers later not to bypass it.


class A:
something_for_contained_to_show = 99
def install_contained (self, B):
B.container = self # Provides B with a reference to A
self.contained = B

class B:
def method_with_container_access (self):
print self.container # Show container object
print self.container.something_for_contained_to_show


<__main__.A instance at 0x019D5788>
99


Does this look like a good idea?


Frederic
 
G

George Sakkis

hi,

I have the following problem: I have two objects, say, A and B, which
are both legitimate stand-alone objects with lives of their own.

A contains B as a property, so I often do

A.B.foo()

the problem is that some functions inside of B actually need A
(remember I said they were both standalone objects), so I have to
often do:

A.B.foo_func(A)

Which is kind of awkward.

Is there some way that B.foo_func() could somehow know that it was
called as a property of A in this way?

Note that I'm looking for the calling object and NOT the calling
function.

Read up on descriptors [1], it seems that's what you're looking for.

HTH,
George

[1] http://users.rcn.com/python/download/Descriptor.htm
 
S

Steven D'Aprano

hi,

I have the following problem: I have two objects, say, A and B, which
are both legitimate stand-alone objects with lives of their own.

A contains B as a property, so I often do

A.B.foo()

the problem is that some functions inside of B actually need A (remember
I said they were both standalone objects),

You contradict yourself.

If the methods inside B *need* A, then B is NOT a standalone object, it
has a dependency, namely A.


so I have to often do:

A.B.foo_func(A)

Which is kind of awkward.

Is there some way that B.foo_func() could somehow know that it was
called as a property of A in this way?

Not in any nice way. There's probably some sort of deep evil black magic
that would work, for some definition of "work" that includes the phrase
"fragile, incomprehensible and risky".

The solution is to admit your dependency instead of living in denial, and
tell B who owns it:

B.owner = A

Now B.foo_func() can refer to B.owner and all is good.


For advanced work, you can make B.owner a weakref to A, and avoid
creating a reference cycle which can sometimes be tricky to deal with.
 
R

Ricardo Aráoz

Maybe this would work for you?
.... def __init__(self, owner=None) :
.... self.owner = owner
.... def someMethod(self) :
.... print self.owner.name
........ def __init__(self, name='class A') :
.... self.B = B(owner=self)
.... self.name = name
....
 
A

afriere

I think the OO way to do this is to provide a method on A that does the
right thing:

    def Bfoo_func(self):
        self.B.foo_func(self)

Or maybe you could look at generic methods, which provide a way
to do multiple dispatch.
+1

Which dispatch would itself be using methods to pass 'self' to the
receiving object. Yes this would seem to be the obvious way to
establish two-way communication between objects. I would be so bold
as to suggest that if the design the OP has adopted is not amenable to
this straightfoward approach, the design needs to be reassessed.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,578
Members
45,052
Latest member
LucyCarper

Latest Threads

Top