我可以获得对 Python 属性的引用吗?

新手上路,请多包涵

如果我有这个:

 class foo(object):
    @property
    def bar(self):
        return 0

f = foo()

如果可能的话,如何在不实际调用方法的情况下获得对 f.bar 的引用?

编辑添加:我想做的是编写一个函数来遍历 f 的成员并对它们做一些事情(什么不重要)。属性让我感到困惑,因为仅仅在 getattr() 中命名它们就会调用它们的 get() 方法。

原文由 kindall 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 390
2 个回答

get_dict_attr (下图)在给定对象的 __dict__ attr 如果存在则返回关联值如果 attr 不是 __dict__ 中的键,则搜索对象的 MRO __dict__ s。如果未找到密钥,则会引发 AttributeError

 def get_dict_attr(obj, attr):
    for obj in [obj] + obj.__class__.mro():
        if attr in obj.__dict__:
            return obj.__dict__[attr]
    raise AttributeError

例如,

 class Foo(object):
    x=1
    def bar(self):
        pass
    @property
    def baz(self):
        return 0

foo=Foo()
print(get_dict_attr(foo,'x'))
# 1
print(get_dict_attr(foo,'bar'))
# <unbound method Foo.bar>
print(get_dict_attr(foo,'baz'))
# <property object at 0xb77c0dc4>
print(get_dict_attr(foo,'y'))
# AttributeError

请注意,这与属性查找的正常规则非常不同。 For one thing, data-descriptors in obj.__class__.__dict__ (descriptors with both __get__ and __set__ methods) normally have precedence over values in obj.__dict__ .在 get_dict_attr 中, obj.__dict__ 具有优先权。

get_dict_attr 不尝试调用 __getattr__

最后, get_dict_attr 仅适用于对象 obj 它们是新型类的实例。

尽管如此,我还是希望它能有所帮助。


 class Foo(object):
    @property
    def bar(self):
        return 0

f = Foo()

这引用了属性 bar

 print(Foo.bar)
# <property object at 0xb76d1d9c>

你看 barFoo.__dict__ 中的一个关键:

 print(Foo.__dict__['bar'])
# <property object at 0xb775dbbc>

所有属性都是描述符,这意味着它有一个 __get__ 方法:

 print(Foo.bar.__get__)
# <method-wrapper '__get__' of property object at 0xb76d7d74>

您可以通过传递对象 ff 的类作为参数来调用该方法:

 print(Foo.bar.__get__(f,Foo))
# 0

我喜欢下面的图表。垂直线表示对象和对象的类之间的关系。

当你遇到这种情况时:

    Foo                                B
   | Foo.__dict__={'bar':b}           | B.__dict__={'__get__':...}
   |                      \           |
   f                       `--------> b

f.bar 导致调用 b.__get__(f,Foo)

这在 此处 详细解释。

原文由 unutbu 发布,翻译遵循 CC BY-SA 3.0 许可协议

简短回答:

从类调用时,属性会返回自身: MyClass.my_prop

此外,它们的字段包含指向实际方法的链接: fgetfsetfdel

描述:

So, my_class.my_prop (where my_class = MyClass() ) returns the value, but MyClass.my_prop returns the property object and MyClass.my_prop.fget returns the getter method of this property . self 没有链接到它,所以它应该在调用期间填充: MyClass.my_prop.fget(my_class)

例子:

 class MyClass:
    my_prop = property(lambda self: 'get', lambda self, x: print('set', x))

setter = MyClass.my_prop.fset
getter = MyClass.my_prop.fget

my_class = MyClass()

setter(my_class, 5)     # equals my_class.my_prop = 5
print(getter(my_class)) # equals print(my_class.my_prop)

原文由 ADR 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题