Python 将元类规则应用于所有子体而不是直接元类

Python 将元类规则应用于所有子体而不是直接元类,python,abstract-class,metaclass,class-members,Python,Abstract Class,Metaclass,Class Members,让我首先定义我的目标: 启用抽象类成员(不是属性、方法或实例成员)的定义,但不使用默认值(不是None或其他神奇值,但如果未实现则会引发错误) 在(1)的服务中,创建一个可重用的抽象机制,使创建具有抽象成员的类变得非常简单,并且使代码尽可能简洁 能够将抽象类成员附加到父类(作为子类、元类或通过任何其他方式),在父类中定义具体子类之前不需要定义抽象成员 到目前为止,我得到的是: 元类_lib.py: class AbstractRequiredClassMembersMetaclass(type)

让我首先定义我的目标:

  • 启用抽象类成员(不是属性、方法或实例成员)的定义,但不使用默认值(不是None或其他神奇值,但如果未实现则会引发错误)

  • 在(1)的服务中,创建一个可重用的抽象机制,使创建具有抽象成员的类变得非常简单,并且使代码尽可能简洁

  • 能够将抽象类成员附加到父类(作为子类、元类或通过任何其他方式),在父类中定义具体子类之前不需要定义抽象成员

  • 到目前为止,我得到的是:

    元类_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()
    
    goods.py(用于说明的实现):

    这不起作用,因为元类在创建
    AbstractGood
    类型
    对象时阻塞。问题是我希望所有具体的商品都定义类成员,但我不想在任何抽象基中定义类成员。我所能想到的就是让元类只在attrs中执行
    检查关键字是否不在
    name
    中(例如
    如果'Abstract'不在name
    中),但这看起来很简陋和脆弱


    有更好的方法吗?

    也是一种黑客行为,但比检查姓名更可靠。 你知道抽象基类没有基类 (或者在python 2中只有
    对象
    类型)。所以你可以检查一下:)


    这也是一种黑客行为,但比检查名字更可靠。 你知道抽象基类没有基类 (或者在python 2中只有
    对象
    类型)。所以你可以检查一下:)


    是的,有更好的办法。使用Python标准库中的。@agf,据我所知,它只允许抽象方法和属性,而不允许抽象类成员。是的,有更好的方法。使用Python标准库中的。@agf,据我所知,它只允许抽象方法和属性,不允许抽象类成员。
    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'
    
    class AbstractBase(object):
       class __metaclass__(type):
            def __new__(mcs, name, bases, dict_):
               if bases[0] is not object: # hack to not apply these on AbstractBase
                    assert 'unit_measure' in dict_
               return type.__new__(mcs, name, bases, dict_)
    
    
    class DeliGood(AbstractBase):
        unit_measure = 'lbs'