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

StackOverflow https://stackoverflow.com/questions/954340

  •  11-09-2019
  •  | 
  •  

Вопрос

В 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__ свойство связанного метода для доступа к экземпляру, к которому привязан метод.

>> 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 который возвращает (несвязанный) объект функции
  • я_сам который возвращает объект, к которому привязана функция (экземпляр класса)
  • im_class который возвращает класс я_сам

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

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_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
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top