有关Python和类特定变量的问题

时间:2013-12-02 19:00:34

标签: python python-2.7

我对python和类初始化变量有疑问。

所以我最近在Python(2.7.X)中注意到,如果设置一个尚未定义或初始化的类变量,您仍然可以调用和访问该变量中的数据。

例如:

class Test:
    def __init__(self):
        self.a = "Hello"


t = Test()
print t.a
t.b = "World"
print t.b

输出:

Hello
World

我希望'print t.b'出错,因为b尚未在Test()类中定义,但它运行没有任何问题。为什么会这样?谁能解释一下?

http://ideone.com/F2LxLh

感谢您的时间。

3 个答案:

答案 0 :(得分:6)

来自instance objects上的文档(t是一个实例对象,因为它是自定义类Test的一个实例):

  

不需要声明数据属性;就像局部变量一样,它们在第一次被分配时就会存在。

但是,__slots__使用new-style class可以获得预期的行为。这会覆盖属性的默认字典存储,以使对象的内存效率更高,如果您尝试分配给__slots__中未定义的属性,也会导致AttributeError,例如:

>>> class Test(object):
...     __slots__ = ['a']
...
>>> t = Test()
>>> t.a = "Hello"
>>> t.b = "World"
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'Test' object has no attribute 'b'

答案 1 :(得分:2)

这是预期的行为。您可以随时在Python中添加属性而不会出现错误。即使没有在__init__中设置属性,您也可以动态添加新属性:

>>> class Test:
...     pass
...
>>> t = Test()
>>> t.foo = '3'
>>> t.foo
'3'

答案 2 :(得分:1)

如果您愿意,可以通过编写自己的__setattr__方法来更改此行为(请参阅docs

class Test:
    def __init__(self):
        self.__dict__[ 'a' ] = "Hello"

    def __setattr__( self, name, value ):
        if name not in self.__dict__:
            raise Exception( 'No attribute: ' + name )
        else:
            self.__dict__[ name ] = value

t = Test()
t.a  = 'hello world'
print ( t.a )
t.b = "World"   # <<< this will throw exception