9.3. OOP Attributes¶
9.3.1. Rationale¶
Attributes are also known as "Properties" or "Fields"
snake_case
name conventionAttributes store information (state) for instances
Access field values using dot (
.
) notationAttributes should be defined only in
__init__()
method (More information in OOP Init Method)
- attribute
- field
Variable inside the class. Can be used as a synonym of property or state.
- property
Variable inside the class. Should not change during lifetime of an object.
- state
Variable inside the class. Changes during lifetime of an object. Represents current state of an object.
- namespace
Container for storing related data
Class example with distinction of properties and state attributes:
Bucket with Water
Properties:
- color
- width
- height
- radius
- capacity
- net mass (without water)
State:
- volume (how much water is currently in bucket)
- gross mass = net mass + water mass (water mass depends on its volume used))

9.3.2. Syntax¶
>>> class Astronaut:
... firstname: str
... lastname: str
>>>
>>>
>>> astro = Astronaut()
>>> astro.firstname = 'Mark'
>>> astro.lastname = 'Watney'
9.3.3. Dynamic Attributes¶
Dynamic attributes:
>>> class Astronaut:
... firstname: str
... lastname: str
>>>
>>>
>>> jose = Astronaut()
>>> jose.firstname = 'José'
>>> jose.lastname = 'Jiménez'
>>>
>>> print(f'My name... {jose.firstname} {jose.lastname}')
My name... José Jiménez
Accessing not existing attributes:
>>> class Astronaut:
... firstname: str
... lastname: str
>>>
>>>
>>> astro = Astronaut()
>>>
>>> print(astro.missions)
Traceback (most recent call last):
AttributeError: 'Astronaut' object has no attribute 'missions'
>>> class Astronaut:
... name: str
>>>
>>>
>>> mark = Astronaut()
>>> jose = Astronaut()
>>> jose.name = 'José Jiménez'
>>>
>>> print(f'My name... {jose.name}')
My name... José Jiménez
>>> print(f'My name... {mark.name}')
Traceback (most recent call last):
AttributeError: 'Astronaut' object has no attribute 'name'
9.3.4. Namespace¶
>>> point_x = 1
>>> point_y = 2
>>> point_z = 3
>>>
>>> print(point_x)
1
>>> print(point_y)
2
>>> print(point_z)
3
>>> class Point:
... x: int
... y: int
... z: int
>>>
>>>
>>> point = Point()
>>> point.x = 1
>>> point.y = 2
>>> point.z = 3
>>>
>>> print(point.x)
1
>>> print(point.y)
2
>>> print(point.z)
3
9.3.5. Different Types¶
>>> class Iris:
... features: list[float]
... label: str
>>>
>>>
>>> setosa = Iris()
>>> setosa.features = [5.1, 3.5, 1.4, 0.2]
>>> setosa.label = 'setosa'
>>>
>>> print(setosa.label)
setosa
>>> print(setosa.features)
[5.1, 3.5, 1.4, 0.2]
>>> sum(setosa.features)
10.2
>>> from typing import Union
>>>
>>> class Astronaut:
... age: Union[float,int]
>>>
>>>
>>> jose = Astronaut()
>>> jose.age = 36
>>>
>>> mark = Astronaut()
>>> mark.age = 42.1
>>> class Astronaut:
... pass
>>>
>>>
>>> jose = Astronaut()
>>> jose.age = 36
>>>
>>> mark = Astronaut()
>>> mark.age = 42.1
9.3.6. Get All Dynamic Attributes and Values¶
obj.__dict__
__dict__
- Getting dynamic fields and values:
>>> class Iris:
... sepal_length: float
... sepal_width: float
... petal_length: float
... petal_width: float
... species: str
>>>
>>>
>>> flower = Iris()
>>> flower.sepal_length = 5.1
>>> flower.sepal_width = 3.5
>>> flower.petal_length = 1.4
>>> flower.petal_width = 0.2
>>> flower.species = 'setosa'
>>>
>>> print(flower.__dict__) # doctest: +NORMALIZE_WHITESPACE
{'sepal_length': 5.1,
'sepal_width': 3.5,
'petal_length': 1.4,
'petal_width': 0.2,
'species': 'setosa'}
9.3.7. Use Cases¶
>>> class Laptop:
... cpu: float
... ram: int
... ssd: int
>>>
>>>
>>> macbook = Laptop()
>>> lenovo = Laptop()
>>> hp = Laptop()
>>> asus = Laptop()
>>> class Date:
... year: int
... month: int
... day: int
>>>
>>>
>>> gagarin_launch = Date()
>>> gagarin_launch.year = 1961
>>> gagarin_launch.month = 4
>>> gagarin_launch.day = 12
>>>
>>> armstrong_first_moon_step = Date()
>>> armstrong_first_moon_step.year = 1969
>>> armstrong_first_moon_step.month = 7
>>> armstrong_first_moon_step.day = 21
>>> class Date:
... year: int
... month: int
... day: int
>>>
>>>
>>> class Person:
... firstname: str
... lastname: str
... date_of_birth: Date
... height: float
... weight: float
>>> class Astronaut:
... firstname: str
... lastname: str
>>>
>>>
>>> watney = Astronaut()
>>> watney.firstname = 'Mark'
>>> watney.lastname = 'Watney'
>>>
>>> lewis = Astronaut()
>>> lewis.firstname = 'Melissa'
>>> lewis.lastname = 'Lewis'
>>> lewis.address = 'Ćwiartki 3/4'
>>>
>>> print(watney.address)
Traceback (most recent call last):
AttributeError: 'Astronaut' object has no attribute 'address'
>>> print(lewis.address)
Ćwiartki 3/4
>>> watney_firstname = 'Mark'
>>> watney_lastname = 'Watney'
>>> watney_mission = 'Ares 3'
>>> watney_agency = 'NASA'
>>>
>>> lewis_firstname = 'Melissa'
>>> lewis_lastname = 'Lewis'
>>> lewis_mission = 'Ares 3'
>>> lewis_agency = 'NASA'
>>> class Astronaut:
... firstname: str
... lastname: str
... mission: str
... agency: str
>>>
>>>
>>> watney = Astronaut()
>>> watney.firstname = 'Mark'
>>> watney.lastname = 'Watney'
>>> watney.mission = 'Ares 3'
>>> watney.agency = 'NASA'
>>>
>>> lewis = Astronaut()
>>> lewis.firstname = 'Melissa'
>>> lewis.lastname = 'Lewis'
>>> lewis.mission = 'Ares 3'
>>> lewis.agency = 'NASA'
>>>
>>> watney.__dict__ # doctest: +NORMALIZE_WHITESPACE
{'firstname': 'Mark',
'lastname': 'Watney',
'mission': 'Ares 3',
'agency': 'NASA'}
>>>
>>> lewis.__dict__ # doctest: +NORMALIZE_WHITESPACE
{'firstname': 'Melissa',
'lastname': 'Lewis',
'mission': 'Ares 3',
'agency': 'NASA'}
9.3.8. Assignments¶
"""
* Assignment: OOP Attribute Model
* Complexity: easy
* Lines of code: 15 lines
* Time: 8 min
English:
1. Use data from "Given" section (see below)
2. Model the data using classes
3. How many classes are there?
4. How many instances are there?
5. Create instances filling it with data
6. Compare result with "Tests" section (see below)
Polish:
1. Użyj danych z sekcji "Given" (patrz poniżej)
2. Zamodeluj dane za pomocą klas
3. Ile jest klas?
4. Ile jest instancji?
5. Stwórz instancje wypełniając je danymi
6. Porównaj wyniki z sekcją "Tests" (patrz poniżej)
Tests:
>>> assert isinstance(watney, Astronaut)
>>> assert isinstance(nasa, SpaceAgency)
>>> assert 'Watney' in watney.__dict__.values()
>>> assert 'USA' in watney.__dict__.values()
>>> assert '1969-07-21' in watney.__dict__.values()
>>> assert 'NASA' in nasa.__dict__.values()
>>> assert 'USA' in nasa.__dict__.values()
>>> assert '1958-07-29' in nasa.__dict__.values()
"""
# Given
"""
Watney, USA, 1969-07-21
NASA, USA, 1958-07-29
"""