1
class A:
    a = 3
    def f(self):
        print self.a

class C(A):
    def __init__(self):
        self.a = 4

>>> a=A()
>>> a.f()
3
>>> c = C()
>>> a.f()
3
>>> c.f()
4

//Update:

>>> C.a = 5
>>> A.a
3
>>> c.a
4

How to explain the result.

Seems like C and A has a different copy of a. In C++ a static member is expected to be shared with its derived class.

2 Answers 2

2

Martin Konecny's answer is mostly correct. There are class-level attributes (which are like static members) and instance-level attributes. All instances share their class attributes (but not their instance attributes), and they can be changed dynamically. Somewhat confusingly, you can get class attributes from an instance with the dot-notation, unless an instance attribute is defined with the same name. Perhaps these examples are illustrative:

 >>> class A:
 ...     a = 3
 ...     def f(self):
 ...         print self.a
 ...
 >>> class C(A):
 ...     def __init__(self):
 ...         self.a = 4
 ...
 >>> a = A()
 >>>
 >>> A.a  # class-level attribute
 3
 >>> a.a  # not redefined, still class-level attribute
 3
 >>> A.a = 5  # redefine the class-level attr
 >>> A.a  # verify value is changed
 5
 >>> a.a  # verify instance reflects change
 5
 >>> a.a = 6  # create instance-level attr
 >>> A.a  # verify class-level attr is unchanged
 5
 >>> a.a  # verify instance-level attr is as defined
 6
 >>> a.__class__.a  # you can still get the class-level attr
 5
 >>>
 >>> c1 = C()
 >>> c2 = C()
 >>> C.a  # this changed when we did A.a = 5, since it's inherited
 5
 >>> c1.a  # but the instance-level attr is still there
 4
 >>> c2.a  # for both instances
 4
 >>> c1.a = 7  # but if we change one instance
 >>> c1.a  # (verify it is set)
 7
 >>> c2.a  # the other instance is not changed
 4
Sign up to request clarification or add additional context in comments.

1 Comment

I think this is more illustrative. See my comment of the Martin Konecny's answer.
1

In python there is a class attribute and an instance attribute

class A:
    a = 3 # here you are creating a class attribute
    def f(self):
        print self.a

class C(A):
    def __init__(self):
        self.a = 4 #here you are creating an instance attribute

Seems like C and A has a different copy of a.

Correct. If you're coming from Java, it's helpful to think of class A as a "static" field, and class C as an "instance" field.

5 Comments

But I can access a by class name C.a. See my updates.
When you said C.a = 5 you created a third attribute. You created a "static" field for class C.
which hide the a in base class A?
There's a small mistake in your code. The last line c.a should print 4. Try it again. If you do C.a you will print the static attribute, if you print c.a you will get the instance attribute.
@goodmami Actually, this is because the asymmetric behavior of __getattr__ and __setattr__. C.a calls __getattr__ which will recursively search a from a->C->A. While C.a = 5 calls __setattr__ which will not do the same searching, and just create a new a which hide the class attribute of A. I just relayed the explanation from some one else, hope its helpful for others. And plz correct if I just missed something.

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.