我有一个抽象基类和定义如下的子类(Python 2.7):
import abc
import MyDatabaseModule
class _DbObject(object):
__metaclass__ = abc.ABCMeta
def _GetObjectType(self):
raise NotImplementedError, "Please override in the derived class"
ObjectType = abc.abstractproperty(_GetObjectType, None)
class Entry(_DbObject):
_objectTypeID = 'ENTRY'
def _GetObjectType(self):
return MyDatabaseModule.DoesSomethingWith(self._objectTypeID)
ObjectType = property(_GetObjectType, None)
这很好用,这意味着无法实例化基类_DbObject
,因为它只有属性getter方法的抽象版本。
try:
dbObject = _DbObject()
print "dbObject.ObjectType: " + dbObject.ObjectType
except Exception, err:
print 'ERROR:', str(err)
现在我可以做:
entry = Entry()
print entry.ObjectType
获得对ObjectType
属性的访问。但是,我想做的只是:
print Entry.ObjectType
但是,无论我在哪里插入@classmethod
,都会出现错误classmethod object is not callabale
。
因此,您需要一个“类属性”-内置property
不能为您提供,但描述符协议可以。描述符协议说的是,每当从类中检索到一个属性时,如果该属性是具有__get__
方法的对象,则该方法将被称为“自我,实例,所有者”,并且如果从类中检索到该属性,代替实例,将“实例”参数设置为None
。
顺便说一句,如@Constantinius所述,这与ABC根本无关,只是与您想要“阶级财产”有关。
class classproperty(object):
def __init__(self, func):
self.func = func
def __get__(self, instance, owner):
return self.func(owner)
class Entry(_DbObject):
_objectTypeID = 'ENTRY'
def _GetObjectType(cls):
return MyDatabaseModule.DoesSomethingWith(cls._objectTypeID)
ObjectType = classproperty(_GetObjectType, None)
ABC
,而是简单的事实,在python中没有classproperty
之类的东西,您必须自己创建它。实际上,有一个很好的question + answer on SO。实际上,将它与您的ABC一起使用也应该没问题。