在python中获取类和实例的属性

Posted

技术标签:

【中文标题】在python中获取类和实例的属性【英文标题】:Get attributes for class and instance in python 【发布时间】:2013-03-01 12:32:48 【问题描述】:

在python中工作下一个代码:

class MyClass(object):
    field = 1

>>> MyClass.field
1

>>> MyClass().field
1

当我想要自定义字段的返回值时,我使用下一个代码:

class MyClass(object):
    def __getattr__(self, name):
       if name.startswith('fake'):
           return name
       raise AttributeError("%r object has no attribute %r" %
                            (type(self).__name__, name))

>>> MyClass().fake
fake

但是:

>>> MyClass.fake
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: class MyClass has no attribute 'fake'

好的,对于我可以使用下一个代码的类:

class MyClassMeta(type):
    def __getattr__(cls, name):
       if name.startswith('fake'):
           return name
       raise AttributeError("%r object has no attribute %r" %
                            (type(self).__name__, name))

class MyClass(object):
    __metaclass__ = MyClassMeta

>>> MyClass.fake
fake

但是:

>>> MyClass().fake
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'MyClass' object has no attribute 'fake'

为了解决这个问题,我使用下一个代码:

class FakeAttrMixin():
   def __getattr__(self, name):
       if name.startswith('fake'):
           return name
       raise AttributeError("%r object has no attribute %r" %
                            (type(self).__name__, name))

class MyClassMeta(type, FakeAttrMixin):
    pass

class MyClass(object, FakeAttrMixin):
    __metaclass__ = MyClassMeta

>>> MyClass.fake
fake

>>> MyClass().fake
fake

MyClass.fake 将使用MyClassfake 参数调用__getattr__

MyClass().fake 将使用MyClass 实例和fake 参数调用__getattr__

如果我只在我的 mixin 上实现 __getattr__ 逻辑并且不使用 self 参数,那也没关系。

我可以编写更漂亮的按类和实例解析的自定义值吗?为什么如果与 __getattr__ 方法相比,MyClass.fieldMyClass().fieldMyClass(object): field = 1 定义的 field 值解析效果不同?因为当我想得到field 时,首先在实例中搜索,然后在课堂上,但我不明白为什么__getattr__ 以另一种方式工作。

类似问题:__getattr__ on a class and not (or as well as) an instance 和 Difference between accessing an instance attribute and a class attribute。

【问题讨论】:

【参考方案1】:

不,如果您必须同时支持对类和实例的任意属性查找,那么您唯一的选择是在元类和类上实现 __getattr__ 挂钩方法,每个都支持查找类和实例。

这是因为特殊的钩子方法总是在类型上查找,所以type(obj).__getattr__。因此,对于MyClass.fake,使用元类__getattr__。见Special method lookup for new-style classes;我解释了为什么这是在previous answer。

简短的原因是,在您的情况下,MyClass.fake 将转换为MyClass.__getattr__('fake'),然后__getattr__ 是一个需要两个 参数(selfname)的未绑定方法,这会失败。

【讨论】:

以上是关于在python中获取类和实例的属性的主要内容,如果未能解决你的问题,请参考以下文章

为啥从类和实例中获取属性的查找过程不同?

Python类和实例方法和属性的动态绑定

Python_类和实例属性的增删改查操作

python 面向对象整理 --------1.类和实例的属性

Python3 OOP 类和实例

类和实例