Получение родительского пространства имен объекта в python?

В python можно использовать '.' для доступа к объектам словаря объекта. Например:

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

Из приведенного выше примера, имея объект «a», можно ли получить от него ссылку на «obj», которая является родительским пространством имен для назначенного метода «foo»? Например, чтобы изменить obj.b на 2?

Python 2.6+ (включая Python 3)

Вы можете использовать свойство __self__ метода bound для доступа к экземпляру, к которому привязан метод.

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

Python 2.2+ (только для Python 2.x)

Вы также можете использовать свойство im_self , но это не совместимо с Python 3.

 >> a.im_self <__main__.test object at 0x782d0> 

По связанным методам вы можете использовать три специальных параметра только для чтения:

  • im_func, который возвращает (unbound) объект функции
  • im_self, который возвращает объект, к которому привязана функция (экземпляр класса)
  • im_class, который возвращает класс im_self

Тестирование вокруг:

 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 ...> 

Здесь есть интересная вещь, которая дает вам подсказку о том, как называются методы:

 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') 

В принципе, атрибут im_self связанного метода изменяется, чтобы разрешить использовать его в качестве первого параметра при вызове im_func

так как синонимы python2.6 для im_self и im_func – это __self__ и __func__ , соответственно. im* атрибуты полностью исчезли в py3k. поэтому вам нужно будет изменить его на:

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