2013-10-26 109 views
0

如何保護類從以這種方式添加屬性:如何保護Python中的類屬性?

class foo(object): 
    pass 

x=foo() 
x.someRandomAttr=3.14 
+1

在類定義中使用'__slots__ =()'。參見['slots'](http://docs.python.org/2/reference/datamodel.html#slots)。 – falsetru

+1

@falsetru:但是,這是一個副作用。 –

+0

你想要一個沒有**任何**屬性的對象嗎?然後使用'x = object()'。 –

回答

4

如果您想要一個不可變的對象,請使用collections.namedtuple() factory爲您創建一個班級:

from collections import namedtuple 

foo = namedtuple('foo', ('bar', 'baz')) 

演示:

>>> from collections import namedtuple 
>>> foo = namedtuple('foo', ('bar', 'baz')) 
>>> f = foo(42, 38) 
>>> f.someattribute = 42 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
AttributeError: 'foo' object has no attribute 'someattribute' 
>>> f.bar 
42 

注意,整個對象是不可變的;在以下事實之後您不能更改f.bar

>>> f.bar = 43 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
AttributeError: can't set attribute 
3

覆蓋的__setattr__方法:

>>> class Foo(object): 
    def __setattr__(self, var, val): 
     raise TypeError("You're not allowed to do this") 
...  
>>> Foo().x = 1 
Traceback (most recent call last): 
    File "<ipython-input-31-be77d2b3299a>", line 1, in <module> 
    Foo().x = 1 
    File "<ipython-input-30-cb58a6713335>", line 3, in __setattr__ 
    raise TypeError("You're not allowed to do this") 
TypeError: You're not allowed to do this 

即使Foo的子類會引發同樣的錯誤:

>>> class Bar(Foo): 
    pass 
... 
>>> Bar().x = 1 
Traceback (most recent call last): 
    File "<ipython-input-35-35cd058c173b>", line 1, in <module> 
    Bar().x = 1 
    File "<ipython-input-30-cb58a6713335>", line 3, in __setattr__ 
    raise TypeError("You're not allowed to do this") 
TypeError: You're not allowed to do this 
+6

這可以防止你設置任何*屬性,包括'__init __()'。 – chepner

+0

@chepner - 你仍然可以通過____設置attrs。醜陋,但可行。 – tdelaney

+0

@chepner:@tdelaney的意思是你只需要使用'self .__ dict __ [''] =​​'。這是一個在重新定義'__setattr__'的類中使用的衆所周知的技術。 – martineau