__getattr__ 用于 class 属性?
__getattr__ for class atributes?
对于 class Foo
,
class Foo:
...
有没有办法在 Foo.XXX
(任意 class 属性 XXX
,例如 bar
、bar2
等时调用特定方法.) 正在被解析,但不是每当 Foo().XXX
(任意实例属性)被解析时?据我所知,重写
def __getattr__(self, a):
...
仅适用于第二种情况。我想从 __getattr__
for instances 仅在未找到相应属性时调用这一事实中受益。有谁知道这应该如何解决?我通读了 the manual,但没有发现任何相关内容。
我并不特别关心如果有人试图为 Foo
的任何 class 或实例属性赋值会发生什么。
用例(避免XY):
Class Foo
是一个使者。 Foo
的实例基本上是带有额外步骤的元组。但是,有 Foo
的特殊情况,我想将其存储为 Foo
的 class 属性(我使用特殊的装饰器管理它)。然而, Foo
的特例数量在逐渐增加,但它们之间的差异很小。每当有人需要 Foo.SPECIAL_CASE_123
时调用这个特殊函数对我来说将是非常有效的 code-wise,因为从 "SPECIAL_CASE_123"
到实际特殊情况的映射非常快并且非常类似于映射 "SPECIAL_CASE_456"
到其他相应的特例。
您可以尝试使用 @classmethod
s:
class Foo:
@classmethod
def XXX(self, a):
return a
print(Foo.XXX('Hello World'))
输出:
Hello World
使用元class 定义classes 的行为方式。具体来说,重新定义 class' __getattr__
以更改 class 上缺失的属性的处理方式:
# The "Type of Foo"
class MetaFoo(type):
def __getattr__(cls, item):
return f"Dynamically handled: {item}"
class Foo(metaclass=MetaFoo):
REGULAR_CASE_22 = "Catch 22"
print(Foo.REGULAR_CASE_22) # Catch 22
print(Foo.SPECIAL_CASE_123) # Dynamically handled: SPECIAL_CASE_123
print(Foo().REGULAR_CASE_22) # Catch 22
print(Foo().SPECIAL_CASE_123) # AttributeError: 'Foo' object has no attribute 'SPECIAL_CASE_123'
请注意,某些属性查找,例如 __add__
等特殊方法,将绕过元class 属性查找。
对于 class Foo
,
class Foo:
...
有没有办法在 Foo.XXX
(任意 class 属性 XXX
,例如 bar
、bar2
等时调用特定方法.) 正在被解析,但不是每当 Foo().XXX
(任意实例属性)被解析时?据我所知,重写
def __getattr__(self, a):
...
仅适用于第二种情况。我想从 __getattr__
for instances 仅在未找到相应属性时调用这一事实中受益。有谁知道这应该如何解决?我通读了 the manual,但没有发现任何相关内容。
我并不特别关心如果有人试图为 Foo
的任何 class 或实例属性赋值会发生什么。
用例(避免XY):
Class Foo
是一个使者。 Foo
的实例基本上是带有额外步骤的元组。但是,有 Foo
的特殊情况,我想将其存储为 Foo
的 class 属性(我使用特殊的装饰器管理它)。然而, Foo
的特例数量在逐渐增加,但它们之间的差异很小。每当有人需要 Foo.SPECIAL_CASE_123
时调用这个特殊函数对我来说将是非常有效的 code-wise,因为从 "SPECIAL_CASE_123"
到实际特殊情况的映射非常快并且非常类似于映射 "SPECIAL_CASE_456"
到其他相应的特例。
您可以尝试使用 @classmethod
s:
class Foo:
@classmethod
def XXX(self, a):
return a
print(Foo.XXX('Hello World'))
输出:
Hello World
使用元class 定义classes 的行为方式。具体来说,重新定义 class' __getattr__
以更改 class 上缺失的属性的处理方式:
# The "Type of Foo"
class MetaFoo(type):
def __getattr__(cls, item):
return f"Dynamically handled: {item}"
class Foo(metaclass=MetaFoo):
REGULAR_CASE_22 = "Catch 22"
print(Foo.REGULAR_CASE_22) # Catch 22
print(Foo.SPECIAL_CASE_123) # Dynamically handled: SPECIAL_CASE_123
print(Foo().REGULAR_CASE_22) # Catch 22
print(Foo().SPECIAL_CASE_123) # AttributeError: 'Foo' object has no attribute 'SPECIAL_CASE_123'
请注意,某些属性查找,例如 __add__
等特殊方法,将绕过元class 属性查找。