是否有某種方法可以在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