## Definition
The collective values held by an [[object]]'s or [[class]]'s [[attribute|attributes]] at a given point in time.
*Noun.*
> A `BankAccount` object's state includes its current balance, which changes every time `deposit()` is called.
## Characteristics
- Used in [[object-oriented programming]];
- a snapshot of the values held by the object's or class's attributes at a given moment;
- changes whenever an attribute's value changes; and
- unique to each [[instance]] when attributes are [[attribute#Instance-level attribute|instance-level]], but shared across all instances when attributes are [[attribute#Class-level attribute|class-level]].
## Examples
### State changes through a method
Calling a method that modifies an attribute changes the object's state. Before `deposit` is called, the `james` object's state includes a `__balance` of `500`; after it is called, the state includes a `__balance` of `550`.
```python
class BankAccount:
def __init__(self, p_owner, p_initial_balance):
self.owner = p_owner
self.__balance = p_initial_balance
def deposit(self, p_amount):
if p_amount > 0:
self.__balance = self.__balance + p_amount
james = BankAccount("James", 500) # state: __balance = 500
james.deposit(50) # state: __balance = 550
```
### State is unique to each instance
Because `__balance` is an [[#Instance-level attribute|instance-level attribute]], each object holds its own independent state. Depositing into `james`'s account does not change `jeremy`'s state.
```python
james = BankAccount("James", 500)
jeremy = BankAccount("Jeremy", 300)
james.deposit(50) # james' state changes; jeremy's does not
```
### Shared state at the class level
Because `interest_rate` is a [[#Class-level attribute|class-level attribute]], it forms part of the shared state of all objects of a class. Changing it affects every instance.
```python
class BankAccount:
interest_rate = 0.03 # part of the class's shared state
def __init__(self, p_owner):
self.owner = p_owner
```
This diagram shows how different `BankAccount` objects can access the class-level `interest_rate` attribute which exists in shared state (provided by the class):
```mermaid
graph BT
Class["BankAccount class<br/>interest_rate = 0.03"]
James["james"]
Jeremy["jeremy"]
James -->|shares state | Class
Jeremy -->|shares state | Class
```
## Non-examples
### Class
A [[class]] is the template from which objects are created and has no state of its own[^1]. A class might, however, determine the initial state of an object including instance and class-level attributes.
### Method
A [[method]] is not state; its behaviour might, however, change state. `deposit()` is a method; the resulting change to `__balance` is the change in state.
```python
def deposit(self, p_amount):
if p_amount > 0:
self.__balance = self.__balance + p_amount # the method changes state; it is not itself state
```
## Notes
[^1]: Strictly speaking, a [[class]] is an [[object]] in Python (see [[Python quirks#Everything is an object]]) and so does actually have state of its own, including the values of all [[attribute#Class-level attribute|class-level attributes]]. However, this level of detail isn't needed to understand the concept practically, and conflicts with the simpler definition of a 'class' you need for your exams.