Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Getting object's parent namespace in python?

In python it's possible to use '.' in order to access object's dictionary items. For example:

class test( object ) :
  def __init__( self ) :
    self.b = 1
  def foo( self ) :
    pass
obj = test()
a = obj.foo

From above example, having 'a' object, is it possible to get from it reference to 'obj' that is a parent namespace for 'foo' method assigned? For example, to change obj.b into 2?

like image 473
grigoryvp Avatar asked Jun 05 '09 05:06

grigoryvp


People also ask

How do you see the parent object in Python?

To access parent class attributes in a child class: Use the super() method to call the constructor of the parent in the child. The __init__() method will set the instance variables. Access any of the parent class's attributes or methods on the self object.

How do you find the namespace in Python?

To get access to local namespace dict you can call locals() or if you want to access any object's namespace call vars(objname) . Inside function if you call locals() or vars() you will get currently visible namespace as dictionary and should not be modified. But inside class/module you get the object's __dict__ .

What is namespace object Python?

Namespaces in Python. A namespace is a collection of currently defined symbolic names along with information about the object that each name references. You can think of a namespace as a dictionary in which the keys are the object names and the values are the objects themselves.


3 Answers

On bound methods, you can use three special read-only parameters:

  • im_func which returns the (unbound) function object
  • im_self which returns the object the function is bound to (class instance)
  • im_class which returns the class of im_self

Testing around:

class Test(object):
    def foo(self):
        pass

instance = Test()
instance.foo          # <bound method Test.foo of <__main__.Test object at 0x1>>
instance.foo.im_func  # <function foo at 0x2>
instance.foo.im_self  # <__main__.Test object at 0x1>
instance.foo.im_class # <__main__.Test class at 0x3>

# A few remarks
instance.foo.im_self.__class__ == instance.foo.im_class # True
instance.foo.__name__ == instance.foo.im_func.__name__  # True
instance.foo.__doc__ == instance.foo.im_func.__doc__    # True

# Now, note this:
Test.foo.im_func != Test.foo # unbound method vs function
Test.foo.im_self is None

# Let's play with classmethods
class Extend(Test):
    @classmethod
    def bar(cls): 
        pass

extended = Extend()

# Be careful! Because it's a class method, the class is returned, not the instance
extended.bar.im_self # <__main__.Extend class at ...>

There is an interesting thing to note here, that gives you a hint on how the methods are being called:

class Hint(object):
    def foo(self, *args, **kwargs):
        pass

    @classmethod
    def bar(cls, *args, **kwargs):
        pass

instance = Hint()

# this will work with both class methods and instance methods:
for name in ['foo', 'bar']:
    method = instance.__getattribute__(name)
    # call the method
    method.im_func(method.im_self, 1, 2, 3, fruit='banana')

Basically, im_self attribute of a bound method changes, to allow using it as the first parameter when calling im_func

like image 107
Nicolas Dumazet Avatar answered Oct 06 '22 17:10

Nicolas Dumazet


Python 2.6+ (including Python 3)

You can use the __self__ property of a bound method to access the instance that the method is bound to.

>> a.__self__
<__main__.test object at 0x782d0>
>> a.__self__.b = 2
>> obj.b
2

Python 2.2+ (Python 2.x only)

You can also use the im_self property, but this is not forward compatible with Python 3.

>> a.im_self
<__main__.test object at 0x782d0>
like image 27
Miles Avatar answered Oct 06 '22 18:10

Miles


since python2.6 synonyms for im_self and im_func are __self__ and __func__, respectively. im* attributes are completely gone in py3k. so you would need to change it to:

>> a.__self__
<__main__.test object at 0xb7b7d9ac>
>> a.__self__.b = 2
>> obj.b
2
like image 43
SilentGhost Avatar answered Oct 06 '22 19:10

SilentGhost