我目前正在开发一个框架,以方便为科学仪器编写控制器程序。我attrs
在代码的内部部分广泛使用。我有一些代码部分公开了要派生的类,但我不想@attr.s
在派生类时一开始就调用。我有一个临时解决方案,但我想知道这个决定是否会让我头疼。
在声明要进一步派生的基类时,我正在使用元类。我使用__new__
元类的来装饰基类。
这是我的代码的精简版本:
import typing as t
import attr
def setting(
unit: str = "",
nicename: t.Optional[str] = None,
default: t.Optional[t.Any] = None):
"""Returns a setting attribute field to be used in InstrumentSettings
derived classes.
Args:
nicename: (optional) A unique nice name for referring to the
setting in texts.
"""
metadata = dict(
metatype='setting',
unit=unit,
nicename=nicename)
return attr.ib(metadata=metadata, default=default)
class _InstrumentSettingsMeta(type):
def __new__(cls, clsname, supers, attrdict):
newcls = super().__new__(cls, clsname, supers, attrdict)
decorated = attr.s(auto_attribs=True)(newcls)
return decorated
class InstrumentSettings(metaclass=_InstrumentSettingsMeta):
pass
# Usage
class FooSettings(InstrumentSettings):
bar: int = setting(default=1)
foosettings = FooSettings()
FooSettings
所以上面的实现给出了完美attrs
装饰的正确行为。问题是我真的不想摆弄元类,因为我认为我没有完全理解它们。如果有人能说明我的方法的缺点和优点,我将不胜感激。我也愿意接受其他建议。