首先,请允许我确定我的目标:
允许定义没有默认值的抽象类成员(不是属性、方法或实例成员)(不是无缺省值或其它魔术价值,而是未执行错误)。
为了服务于第(1)条,建立一个可重复使用的抽象机制,使建立具有抽象成员的班级变得微不足道,而守则则尽量简明扼要。
有能力将抽象的阶级成员(作为子阶级、元阶级或以任何其他方式)附在母阶级上,在确定具体的子阶级之前,不需要界定抽象的阶级成员。
我到现在为止得到的是:
sequal_lib.py :
class AbstractRequiredClassMembersMetaclass(type):
def __new__(cls, name, bases, attrs):
missed_members = []
for class_member in cls.REQUIRED_CLASS_MEMBERS:
if class_member not in attrs:
missed_members.append(class_member)
if missed_members:
raise NotImplementedError( Class missing required members %s. % missed_members)
return super(AbstractRequiredClassMembersMetaclass, cls).__new__(cls, name, bases, attrs)
class _MakeRequiredClassMemebersMetaclass(object):
existing_classes = {}
def __call__(self, name, required_members):
if name in _MakeRequiredClassMemebersMetaclass.exisiting_classes:
if required_members != _MakeRequiredClassMemebersMetaclass.exisiting_classes[name].REQUIRED_CLASS_MEMBERS:
raise RuntimeError( Class of name %s already defined with different required_members. % name)
else:
NewClass = type(name, (AbstractRequiredClassMembersMetaclass,), { REQUIRED_CLASS_MEMBERS : required_members})
_MakeRequiredClassMemebersMetaclass.exisiting_classes[name] = NewClass
return _MakeRequiredClassMemebersMetaclass.exisiting_classes[name]
make_required_class_members_metaclass = _MakeRequiredClassMemebersMetaclass()
(实施说明):
from metaclass_lib import make_required_class_members_metaclass
class AbstractGood(object):
__metaclass__ = make_required_class_members_metaclass( AbstractGoodMeta , ( unit_measure ,))
def __init__(self):
self.unit_price = None
def total_cost(self, number_of_units):
return self.unit_price * self.number_of_units
class DeliGood(AbstractGood):
unit_measure = lbs
def __init__(self):
self.sandwich_counter_product = False
class RefridgeratedGood(AbstractGood):
unit_measure = package
def __init__(self):
self.freezer_safe = False
self.optimal_temp = 35
这不起作用, 因为创建 < code> AbstractGood < code> < type> > 对象时, 元类会窒息。 问题是我要所有具体货物定义该类成员, 但我不想在任何抽象基数中定义该类成员。 我所能想到的是, 如果关键字不在 < code> name (ex < code> implete not in name ) 中, 但似乎不可靠, 元类只使用 attrs code> 中 < code > 的 < code > 检查。
有更好的办法吗?