[基于python 3.4编写的答案;元类的语法在2中有所不同,但我认为该技术仍然有效]
您可以使用元类...主要做到这一点。 Dappawit几乎工程,但我认为它也有缺陷:
class MetaFoo(type):
@property
def thingy(cls):
return cls._thingy
class Foo(object, metaclass=MetaFoo):
_thingy = 23
这让你一个classproperty上富,但有一个问题...
print("Foo.thingy is {}".format(Foo.thingy))
# Foo.thingy is 23
# Yay, the classmethod-property is working as intended!
foo = Foo()
if hasattr(foo, "thingy"):
print("Foo().thingy is {}".format(foo.thingy))
else:
print("Foo instance has no attribute 'thingy'")
# Foo instance has no attribute 'thingy'
# Wha....?
这到底是怎么回事?为什么我无法通过实例访问类属性?
在找到我相信的答案之前,我在这上面打了很久。 Python的@properties是描述符的一个子集,并从descriptor documentation(重点煤矿):属性的访问
默认行为是获取,设置或删除对象的字典中 属性。例如,a.x
具有查找链 开始a.__dict__['x']
,然后type(a).__dict__['x']
,并继续通过 type(a)
不含元类的基类。
所以方法解析顺序不包括我们的类属性(或其他在元类中定义的)。它是可能使内置属性装饰器的行为有所不同,但(引文需要)我得到了印象谷歌搜索开发人员有一个很好的理由(我不明白)做到这一点办法。
这并不意味着我们运气不好;我们可以在类本身就好访问属性...我们可以从type(self)
实例,我们可以用它来使@property调度中获取类:
class Foo(object, metaclass=MetaFoo):
_thingy = 23
@property
def thingy(self):
return type(self).thingy
现在Foo().thingy
作品用于两个班级和实例!如果一个派生类替代了它的基础_thingy
(这是最初让我参与这个狩猎的用例),它也将继续做正确的事情。
这对我来说并不是100%满意 - 必须在元类和对象类中进行设置才会感觉违反了DRY原则。但后者只是一个单线调度员;我现在大部分都没问题,如果你真的想要的话,你可以把它压缩到一个lambda或什么东西。
我不知道python ...这是你正在寻找的东西吗? http://www.python.org/download/releases/2。2/descrintro /#属性 – 2011-03-04 04:40:48
如果我正在阅读这个权利,你可以创建方法来充当setter和getter(和其他语言一样),这样你就可以在第一次获取属性值时进行懒加载...我认为你想要什么? – 2011-03-04 04:45:56
@白龙。您正在查看的属性功能将类属性添加到类实例中,而不是类本身。我在问'Example.I'不是'e.i'。 – 2011-03-04 04:57:04