是否有某种方法可以在Python中创建类级别的只读属性?举例来说,如果我有一个类Foo
,我想说:Python中的类级别只读属性
x = Foo.CLASS_PROPERTY
而是阻止任何人说:
Foo.CLASS_PROPERTY = y
编辑: 我喜欢的Alex Martelli's solution简单,但不它需要的语法。无论他和~unutbu's answer默示以下解决方案,这是接近到的精神是我一直在寻找:
class const_value (object):
def __init__(self, value):
self.__value = value
def make_property(self):
return property(lambda cls: self.__value)
class ROType(type):
def __new__(mcl,classname,bases,classdict):
class UniqeROType (mcl):
pass
for attr, value in classdict.items():
if isinstance(value, const_value):
setattr(UniqeROType, attr, value.make_property())
classdict[attr] = value.make_property()
return type.__new__(UniqeROType,classname,bases,classdict)
class Foo(object):
__metaclass__=ROType
BAR = const_value(1)
BAZ = 2
class Bit(object):
__metaclass__=ROType
BOO = const_value(3)
BAN = 4
现在,我得到:
Foo.BAR
# 1
Foo.BAZ
# 2
Foo.BAR=2
# Traceback (most recent call last):
# File "<stdin>", line 1, in <module>
# AttributeError: can't set attribute
Foo.BAZ=3
#
我喜欢这个解决方案,因为:
- 成员得到声明为内联,而不是在事后,与
type(X).foo = ...
- 成员的值在实际类的代码中设置,而不是在元类的代码中设置。
它仍然并不理想,因为:
- 我必须设置
__metaclass__
为了正确解释const_value
对象。 - 该
const_value
s不“行为”像朴素的价值观。例如,我无法将它用作类中某个方法的参数的默认值。
为什么有人会尝试设置Foo.CLASS_PROPERTY? Python中的典型风格是在规划时选择简单性,以防止某个人做某些愚蠢的理论实例。你无法做任何事情来阻止人们用你的代码来做愚蠢的事情。 – 2009-11-14 23:15:27
@Mike:你是对的;常识会告诉人们不要修改这些属性。然而,偶尔他们会被修改。这就是为什么我喜欢它被拼写出来(比全部大写更明确)。与使用私人会员的理由相同。显式接口很好。不要误解我的意思:我也喜欢简单。我更喜欢如果有一些内置的设施(比如@classproperty装饰器或其他)。事实上,如果每次都需要设置'__metaclass__',我甚至不确定是否会使用上述解决方案。现在,全部大写可能会赢。 – mjumbewu 2009-11-15 00:07:22
未来人们的注意事项:现代python版本可以在新式类中使用'@ property':http://docs.python.org/library/functions.html#property – 2012-06-07 15:12:35