2

Python 3.4.0a1
Windows 8.1

Class Created:

class Bank(object):  
    bankrupt = False  

Command entered in IDLE __main__ with the following results:

>>> a = Bank()
>>> b = Bank()
>>> a.bankrupt
False
>>> b.bankrupt
False
>>> b.bankrupt = True
>>> b.bankrupt
True
>>> a.bankrupt
False

Expected output:

I expected a.bankrupt to change to True when I changed b.bankrupt since the variable bankrupt is defined for the entire class and not for a single instance (with self.bankrupt) Why is this not happening?

1
  • From a modelling perspective, shouldn't individual Bank instances be able to go bankrupt separately? Commented Jun 30, 2014 at 7:36

3 Answers 3

6

You assigned to a new attribute to the instance instead. To change a class attribute, assign directly to the class.

When looking up an attribute on an instance, look-up 'falls through' to the class, then to the base classes. This is how all class attributes, including methods, are found.

But when assigning, this happens directly on the instance. Otherwise you could never assign per-instance values, you'd only ever assign back to the class. Assigning to a.bankrupt or b.bankrupt will add an attribute to the instance, if it wasn't already there to begin with. To Python, there is no difference between using self.bankrupt = True in a method, or to using a.bankrupt = True from the 'outside' to assign to an attribute.

Just assign to the class attribute directly (from a method or from 'outside'):

Bank.bankrupt = True

Note that the same fall-through on read, assignment on write rules apply to base classes; looking up an attribute on a class looks to the base classes if the attribute is not found on the class directly, but setting an attribute on a class do so directly, and not affect attributes on the bases.

For the nitty gritty details, see the Custom classes and Class instances sections of the Python datamodel.

Sign up to request clarification or add additional context in comments.

Comments

0

With b.bankrupt = True you create an instance variable that shadows the class-level variable.

If you want to change the class variable use

Bank.bankrupt = True

1 Comment

So there is now both an instance variable for b and a class variable called bankrupt?
0

After assignment to instance variable it is created if it was not before. And next time You try to access it You got it from instance __dict__.

>>> class A:
...     foo = 'b'
...     bar = []
... 
>>> a = A()
>>> b = A()
>>> a.__dict__
{}
>>> a.foo = 'c'
>>> a.foo
'c'
>>> a.__dict__
{'foo': 'c'}

This is why You have different values for a.foo and b.foo Meanwhile If You modify variable (not reassign it) You will got result which You have described.

>>> a.bar.append(1)
>>> b.bar
[1]
>>> a.bar
[1]
>>> a.__dict__
{'foo': 'c'}

In this case instance variable was not created.

1 Comment

Note that when you use __slots__ on the class no __dict__ is used.

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.