我可以获得对 Python 属性的引用吗? [英] Can I get a reference to a Python property?

查看:36
本文介绍了我可以获得对 Python 属性的引用吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果我有这个:

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

f = foo()

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

How do I get a reference to f.bar without actually invoking the method, if this is even possible?

编辑补充:我想要做的是编写一个函数来遍历 f 的成员并对其进行处理(什么不重要).属性让我感到困惑,因为仅仅在 getattr() 中命名它们会调用它们的 __get__() 方法.

Edited to add: What I want to do is write a function that iterates over the members of f and does something with them (what is not important). Properties are tripping me up because merely naming them in getattr() invokes their __get__() method.

推荐答案

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

get_dict_attr (below) looks up attr in a given object's __dict__, and returns the associated value if its there. If attr is not a key in that __dict__, the object's MRO's __dict__s are searched. If the key is not found, an AttributeError is raised.

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

请注意,这与属性查找的正常规则非常不同.一方面,obj.__class__.__dict__ 中的数据描述符(同时具有 __get____set__ 方法的描述符)通常优先于 <代码>obj.__dict__.在 get_dict_attr 中,obj.__dict__ 优先.

Note that this is very different than the normal rules of attribute lookup. For one thing, data-descriptors in obj.__class__.__dict__ (descriptors with both __get__ and __set__ methods) normally have precedence over values in obj.__dict__. In get_dict_attr, obj.__dict__ has precedence.

get_dict_attr 不会尝试调用 __getattr__.

最后,get_dict_attr 只适用于对象 obj,它们是新式类的实例.

Finally, get_dict_attr will only work with objects obj which are instances of new-style classes.

不过还是希望对大家有帮助.

Nevertheless, I hope it is of some help.

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

f = Foo()

这引用了属性bar:

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

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

You see bar is a key in Foo.__dict__:

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

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

All properties are descriptors, which implies it has a __get__ method:

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

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

You can call the method by passing the object f, and the class of f as arguments:

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

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

I am fond of the following diagram. Vertical lines show the relationship between an object and the object's class.

当您遇到这种情况时:

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

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

这个有详细解释此处.

这篇关于我可以获得对 Python 属性的引用吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆