【发布时间】:2022-01-02 23:31:03
【问题描述】:
我在创建一个元类时遇到了一个错误,该元类动态地创建具有给定配置文件的属性的类。
更详细地说,我希望动态创建具有某些属性的类(常规 setter 和在该属性上运行自定义函数结果的 getter)。所以我创建了一个工厂类来在运行时注册类和一个元类来设置给定配置字典的属性。
from copy import deepcopy
from typing import Any, Callable, Dict, Tuple
class Meta(type):
def __new__(
cls,
clsname: str,
bases: Tuple,
attrs: Dict[str, Any],
fields: Dict[str, Callable] = None,
) -> object:
if fields is not None:
for field, field_fn in fields.items():
attrs[f"_{field}"] = None
attrs[f"{field}"] = property(
fget=lambda self: deepcopy(field_fn)(getattr(self, f"_{field}")),
fset=lambda self, value: setattr(self, f"_{field}", value),
)
return super().__new__(cls, clsname, bases, attrs)
class Factory:
registry = {}
@classmethod
def register(
cls,
name: str,
cfg: Dict[str, Callable],
) -> None:
class ConfigurableClass(metaclass=Meta, fields=cfg):
pass
Factory.registry[name] = ConfigurableClass
@classmethod
def make(cls, name: str):
return cls.registry[name]()
if __name__ == "__main__":
Factory.register("foo", {"a": lambda x: x + 1, "b": lambda x: x - 1})
obj = Factory.make("foo")
obj.a = 5
obj.b = 5
print(obj.a, obj.b)
# Expected 6 and 4 but get 4 and 4 instead
但是,由于某种原因,最后一个 dict 键的功能被注册为 all 属性。我什至尝试在其中添加deepcopy。
感谢任何帮助,谢谢。
【问题讨论】:
标签: python python-3.x properties metaclass