【问题标题】:Is there a way to use __getattr__ as Python classmethod有没有办法使用 __getattr__ 作为 Python classmethod
【发布时间】:2022-11-18 05:59:30
【问题描述】:
获取属性与类的实例一起工作得很好:
class Person:
def __getattr__(self, name):
print(name)
p = Person()
p.john
输出:
john
但它不能作为类方法工作:
class Person:
@classmethod
def __getattr__(cls, name):
print(name)
Person.john
输出:
AttributeError: type object 'Person' has no attribute 'john'
有没有办法使用获取属性直接上课?
【问题讨论】:
标签:
python-3.x
oop
getattr
【解决方案1】:
__getattr__,像大多数特殊方法一样,只在实例的类上查找(绕过实例本身)。由于您试图在类本身上调用它,因此必须在 class Person 正在实现的类上定义它。默认情况下是type(所有类类型的公共根)。
如果你真的需要这样做(我怀疑an XY problem)你可以用元类(类本身的类)来做到这一点:
class PersonMeta(type):
def __getattr__(cls, name):
print(cls, name)
class Person(metaclass=PersonMeta):
def __getattr__(self, name):
return getattr(type(self), name) # Delegate to metaclass implementation
Person.john
Person().john
Try it online!
请注意,您需要在类本身上实现委托版本,以确保它委托回元类的实现(假设您希望能够让它在类的实例上运行,而不仅仅是在类本身上运行)。如果元类的类的所有实例都应展示此委托行为,则元类本身可以在构造时(在__prepare__ 或__new__ 中)动态地将此类方法附加到类。