0

My code:

>>> class Class1:
    pass

>>> obj1=Class1()
>>> obj2=Class1()
>>> obj1.x1=123
>>> obj2.x2=456

Then I got the following errors:

>>> obj1.x2

Traceback (most recent call last):
  File "<pyshell#9>", line 1, in <module>
    obj1.x2
AttributeError: Class1 instance has no attribute 'x2'

And similarly:

>>> obj2.x1

Traceback (most recent call last):
  File "<pyshell#11>", line 1, in <module>
    obj2.x1
AttributeError: Class1 instance has no attribute 'x1'

The AttributeError is quite strange, why it says the Class1 has no attribute 'x1' and 'x2'? Python claims to be able to add fields on the fly. And I am expecting result like this:

obj1.x2 = None
obj2.x1 = None

What's the difference between the field add on the fly and the contained in the class definition?

7
  • 1
    What on earth is obj1 and obj2? Commented Jan 10, 2014 at 14:16
  • Missing an obj1 = Class1() in your example? Commented Jan 10, 2014 at 14:17
  • Sorry, it was in my code. I just missed in my question. Updated. Commented Jan 10, 2014 at 14:18
  • 1
    What on earth is Class2 ? Commented Jan 10, 2014 at 14:19
  • 1
    obj1.x2 causes an error because obj1 has no x2 attribute -- you added that attribute to the obj2 instance of class Class1, which does not automatically add it to the existing obj1 instance. Commented Jan 10, 2014 at 14:25

2 Answers 2

3

If obj1 is an instance of Class1 then it is adding variables on an instance-based level.

This can be seen as below

class Test(object): pass 
a = Test()
b = Test()
a.a = 4
print a.a
print b.a # Attribute error here.

If you mean to add a class level variable, apply this to Test directly

Test.a = 432
print b.a
print a.a
Sign up to request clarification or add additional context in comments.

3 Comments

So there's a difference between class-level and instance-level variables. That's quite different from the traditional OOP thinking.
@smwikipedia only in a sense that adding variables to existing objects is strange.
@smwikipedia: The converse actually doesn't make much sense, as the case of all variables being class-level variables would result in shared state between all instances. You'd have a collection of references to a singleton class.
1

What's the difference between the field add on the fly and the contained in the class definition?

This is in class definition:

>>> class Class1:
    x = None

Proof:

>>> Class1().__dict__
{}
>>> Class1.__dict__
{'x': None, '__module__': '__main__', '__doc__': None}

This at instance level:

>>> class Class1:
    def __init__(self):
    self.x = None

Proof:

>>> Class1.__dict__
{'__module__': '__main__', '__doc__': None, '__init__': <function __init__ at 0x000000000241C358>}
>>> Class1().__dict__
{'x': None}

Adding attribute on the fly adds the attribute at the instance level not the class level

Proof:

>>> class Class1: pass
... 
>>> foo = Class1()
>>> foo.__dict__
{}
>>> foo.x = None
>>> foo.__dict__
{'x': None}
>>> Class1.__dict__
{'__module__': '__main__', '__doc__': None}

You can add attributes to class definition on the fly too.

Proof:

>>> class Class1: pass
... 
>>> Class1.__dict__
{'__module__': '__main__', '__doc__': None}
>>> Class1().__dict__
{}
>>> Class1.x = None
>>> Class1.__dict__
{'x': None, '__module__': '__main__', '__doc__': None}
>>> Class1().__dict__
{}
>>> Class1().x
>>> print Class1().x
None

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.