English 中文(简体)
对所有后代适用元类规则,而不是直接的元类
原标题:Applying metaclass rules to all descendants rather than direct metaclassed class

首先,请允许我确定我的目标:

  1. 允许定义没有默认值的抽象类成员(不是属性、方法或实例成员)(不是无缺省值或其它魔术价值,而是未执行错误)。

  2. 为了服务于第(1)条,建立一个可重复使用的抽象机制,使建立具有抽象成员的班级变得微不足道,而守则则尽量简明扼要。

  3. 有能力将抽象的阶级成员(作为子阶级、元阶级或以任何其他方式)附在母阶级上,在确定具体的子阶级之前,不需要界定抽象的阶级成员。

我到现在为止得到的是:

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 > 检查。

有更好的办法吗?

问题回答

Also a hack, but more reliable than checking the name. You know that an Abstract Base Class has no base classes (or has only object type in python 2). So you could check for that :)

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 




相关问题
Can Django models use MySQL functions?

Is there a way to force Django models to pass a field to a MySQL function every time the model data is read or loaded? To clarify what I mean in SQL, I want the Django model to produce something like ...

An enterprise scheduler for python (like quartz)

I am looking for an enterprise tasks scheduler for python, like quartz is for Java. Requirements: Persistent: if the process restarts or the machine restarts, then all the jobs must stay there and ...

How to remove unique, then duplicate dictionaries in a list?

Given the following list that contains some duplicate and some unique dictionaries, what is the best method to remove unique dictionaries first, then reduce the duplicate dictionaries to single ...

What is suggested seed value to use with random.seed()?

Simple enough question: I m using python random module to generate random integers. I want to know what is the suggested value to use with the random.seed() function? Currently I am letting this ...

How can I make the PyDev editor selectively ignore errors?

I m using PyDev under Eclipse to write some Jython code. I ve got numerous instances where I need to do something like this: import com.work.project.component.client.Interface.ISubInterface as ...

How do I profile `paster serve` s startup time?

Python s paster serve app.ini is taking longer than I would like to be ready for the first request. I know how to profile requests with middleware, but how do I profile the initialization time? I ...

Pragmatically adding give-aways/freebies to an online store

Our business currently has an online store and recently we ve been offering free specials to our customers. Right now, we simply display the special and give the buyer a notice stating we will add the ...

Converting Dictionary to List? [duplicate]

I m trying to convert a Python dictionary into a Python list, in order to perform some calculations. #My dictionary dict = {} dict[ Capital ]="London" dict[ Food ]="Fish&Chips" dict[ 2012 ]="...

热门标签