By instantiating the class and accessing self.crisis
means that (among many things) the __init__()
is called. The init in the class, or inherited classes will be "called" and consequences of the call could change crisis
.
By contrast, Bank.crisis
think of as a simple variable for a class in how it behaves. Not encapsulated, not modified from an original state.
Now that is the short and simple answer, there are a lot of other things to know about, but I am trying to highlight an easy and critical difference with respect to the question.
To elaborate on the code more, the use of crisis
is a flag or escape from an iterable/while/generator type situation. Something else in the code, (possibly in an inherited class, probably not however) will flip crisis
to True
or some other value. To use crisis
as a control self
will be part of the use generally as that variable, via initialization, is encapsulated where only via self
will the value "in the instance" be of value with respect to the code's desired flow. The self.
"something" is inside the instantiated class and can change as needed in any operation providing functionality. This is the core of OOP, variables, etc, are not fixed, they can change dynamically in use, and that allows crisis
to change and alter behavior in the instance safely (encapsulated).
To drive the point home:
b = Bank()
b.crisis # starts off as false, probably
# is not the same (any more) as
Bank.crisis # False
# because now
b.crisis = "foo"
# is in the instance while
Bank.crisis # will always return False.