【问题标题】:Getting object's parent namespace in python?在python中获取对象的父命名空间?
【发布时间】:2010-10-31 13:25:42
【问题描述】:

在 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 python-datamodel


    【解决方案1】:

    在绑定方法上,可以使用三个特殊的只读参数:

    • im_func 返回(未绑定的)函数对象
    • 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

    时将其用作第一个参数

    【讨论】:

      【解决方案2】:

      Python 2.6+(包括 Python 3)

      您可以使用__self__ property of a bound method 访问该方法绑定到的实例。

      >> 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_self O_O。非常感谢!
      • 使用 dir() 是发现类似情况的好方法:dir(obj.foo)
      • 但我需要做完全相反的操作:obj from a :)
      • 我的意思是在交互式提示下,用于学习目的。您可以查看不同类型的对象具有哪些方法和属性;因此,如果您有一个实例方法,您可以在其上使用 dir() 并查看是否有任何属性将您引导回该对象。此外,dir(obj.foo) 与 dir(a) 相同。
      • 我认为 Miles 很高兴您告诉他两个功能相反的功能。无论哪种方式,我都觉得很有趣。
      【解决方案3】:

      因为im_selfim_func的python2.6同义词分别是__self____func__im* 属性在 py3k 中完全消失了。因此您需要将其更改为:

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

      【讨论】:

      • im_class的同义词是__self__.__class__
      • 啊,我应该向下滚动的。
      猜你喜欢
      • 2019-11-16
      • 1970-01-01
      • 2012-06-12
      • 1970-01-01
      • 2011-09-19
      • 2018-03-14
      • 1970-01-01
      • 2016-12-17
      • 1970-01-01
      相关资源
      最近更新 更多