是否可以在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
值所需的所有信息都存储在静态变量中。
答案 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__
在构造类 时执行,而不是构造对象。因此,除非您动态创建类,否则它只会被调用一次。