python中的静态成员初始化来自派生类的静态成员值

时间:2017-07-30 16:09:00

标签: python python-2.7 sqlite oop orm

是否可以在python(2.7)中从派生类的静态成员初始化基类的静态成员?

即,假设我有一堆类来映射存储在简单数据库中的实体:

class EntityA(EntityBase):
    entityName = 'EntA' # the name of the entity in the DB
    ...

class EntityB(EntityBase):
    entityName = 'EntB' # the name of the entity in the DB
    ...

并假设数据库的构建遵循以下规则:所有实体都有一个名为“id_ name of of the-entity ”的id字段。因此,'id_EntA'和'id_EntB'分别是EntityA和EntityB的DB中id字段的名称。

现在我想从(抽象)基类(EntityBase)中生成这两个名称只有一次,但我找不到办法做到这一点......

我想写一些类似的东西:

class EntityBase:
    idFieldName = 'id_' + *derived-class*.entityName
    ...

我知道我可以编写一个返回连接字符串的简单函数,但我希望每次调用该函数时都不会对它进行求值。这应该是可能的,因为构建idFieldName值所需的所有信息都存储在静态变量中。

1 个答案:

答案 0 :(得分:0)

您可以使用的是metaclass。元类是某个类所属的类。

然后你可以使用:

class MetaEntityBase(type):
    def __new__(meta, name, bases, dct):
        if 'entityName' in dct:
            dct['idFieldName'] = 'id_'+dct['entityName']
        return super(MetaEntityBase,meta).__new__(meta,name,bases,dct)

然后你可以写:

class EntityBase:
    __metaclass__ = MetaEntityBase

现在如果我们查询EntityA.idFieldName,我们会得到:

>>> EntityA.idFieldName
'id_EntA'

我们首先使用if语句检查dct dct是一个包含初始化之前的类成员的字典:所以它包含所有方法,类字段等。

因此,我们检查'entityName'是否是其中一个键(这意味着在类级别,它是在某处定义的)。如果是这种情况,我们会向dct添加一个新元素:'idFieldName',其前缀为entityName id_。当然,如果没有这样的属性else

,您可以定义entityName案例。

元类的__new__ 在构造 时执行,而不是构造对象。因此,除非您动态创建类,否则它只会被调用一次。