Ste*_*eve 0 python metaclass class dynamic
在 Python 中,您可以动态实现类实例的属性,这已不是什么秘密。看起来是这样的:
class MyClass(object):
def __getattribute__(self, name):
if name == 'dynamic_attribute':
return "dynamic attribute value"
return super().__getattribute__(name)
# Create an instance of my class
obj = MyClass()
# I've implemented the 'dynamic_attribute' attribute dynamically, so I can
# reference it without ever having assigned it a value
print(obj.dynamic_attribute)
# As I've only implemented that one attribute dynamically, other attributes
# behave in the standard way
try:
print(obj.regular_attribute)
except AttributeError as ex:
print(f"EXPECTED ERROR: {ex}")
obj.regular_attribute = "regular attribute value"
print(obj.regular_attribute)
Run Code Online (Sandbox Code Playgroud)
结果:
dynamic attribute value
EXPECTED ERROR: 'MyClass' object has no attribute 'regular_attribute'
regular attribute value
Run Code Online (Sandbox Code Playgroud)
有没有办法用类属性而不是类实例属性来做同样的事情?这是一个例子:
print(MyClass.dynamic_class_attribute)
Run Code Online (Sandbox Code Playgroud)
我希望这行代码返回一个在我的代码中某处计算的值,而不必在 MyClass 类上显式定义“dynamic_class_attribute”属性。这可以做到吗?TIA。
PS:我从未对元类做过任何事情,但我知道它们的存在。我读了一些关于他们的文章,希望能找到这个问题的明显答案。我没有找到。
更新:
有人问我为什么要这个。也许其他人会发现我的用例很有趣。我基本上只是在简化我正在创建的 API 方面有点疯狂。它并不像这样简单,但它基本上是一个单例的事情,我真正要做的就是尝试替换它:
SomeSingletonClass.get().some_method()
Run Code Online (Sandbox Code Playgroud)
有了这个:
SomeSingletonClass.some_method()
Run Code Online (Sandbox Code Playgroud)
在任何时刻,都只有一个 SomeSingletonClass 实例,并且我经常引用该实例,因此我想尽可能简化对它的全局引用。根据 Raymond H 的回答,我做到了。效果很好。
有没有办法用类属性而不是类实例属性来做同样的事情?
是的,只需将逻辑移至元类中即可:
class MyMetaClass(type):
def __getattribute__(self, name):
if name == 'dynamic_attribute':
return "dynamic attribute value"
return super().__getattribute__(name)
class C(metaclass=MyMetaClass):
pass
print(C.dynamic_attribute)
Run Code Online (Sandbox Code Playgroud)
基本思想是常规类控制实例的行为,元类控制类的行为。
| 归档时间: |
|
| 查看次数: |
191 次 |
| 最近记录: |