FunkyFresh
FunkyFresh

Reputation: 237

Questions regarding Python and Class specific variables

I have a question regarding python and class initialized variables.

So I recently noticed in Python (2.7.X) that if you set a class variable that hasn't been defined or initialized, you are still able to call and access the data within that variable.

For instance:

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


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

Output:

Hello
World

I would expect 'print t.b' to error because b hasn't been defined in the Test() class but it runs without any issue. Why is this happening? Can anyone explain?

http://ideone.com/F2LxLh

Thank you for your time.

Upvotes: 1

Views: 61

Answers (3)

behzad.nouri
behzad.nouri

Reputation: 78021

If you want you can change this behavior by writing your own __setattr__ method ( see 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

Upvotes: 1

Andrew Clark
Andrew Clark

Reputation: 208705

From the docs on instance objects (t is an instance object because it is an instance of the custom class Test):

Data attributes need not be declared; like local variables, they spring into existence when they are first assigned to.

However you can get your expected behavior by using __slots__ with a new-style class. This overrides the default dictionary storage for attributes to make the object more memory efficient, and it also results in an AttributeError if you try to assign to an attribute not defined in __slots__, for example:

>>> 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'

Upvotes: 6

Simeon Visser
Simeon Visser

Reputation: 122526

This is expected behaviour. You can add attributes in Python at any time without errors. Even without setting attributes in the __init__ you can add new ones on the fly:

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

Upvotes: 2

Related Questions