6.8. Operator Increment¶
x += y
- will call method "iadd" on objectx
(x.__iadd__(y)
)x -= y
- will call method "isub" on objectx
(x.__isub__(y)
)x *= y
- will call method "imul" on objectx
(x.__imul__(y)
)x **= y
- will call method "ipow" on objectx
(x.__ipow__(y)
)x @= y
- will call method "imatmul" on objectx
(x.__imatmul__(y)
)x /= y
- will call method "itruediv" on objectx
(x.__itruediv__(y)
)x //= y
- will call method "ifloordiv" on objectx
(x.__ifloordiv__(y)
)x %= y
- will call method "imod" on objectx
(x.__imod__(y)
)
Operator |
Method |
---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
>>> x = 0
>>> id(x)
4406492680
>>>
>>> x += 1
>>> id(x)
4406492712
>>> x = 1
>>> id(x)
4406492712
>>>
>>> x += 0
>>> id(x)
4406492712
>>> x = [1, 2, 3]
>>> id(x)
4343115776
>>>
>>> x += [4, 5, 6]
>>> id(x)
4343115776
6.8.1. SetUp¶
>>> from dataclasses import dataclass, field
6.8.2. Syntax¶
>>> @dataclass
... class Vector:
... x: int
... y: int
...
... def __iadd__(self, other): ... # x += y calls x.__iadd__(y)
... def __isub__(self, other): ... # x -= y calls x.__isub__(y)
... def __imul__(self, other): ... # x *= y calls x.__imul__(y)
... def __ipow__(self, power, modulo=None): ... # x **= y calls x.__ipow__(y)
... def __imatmul__(self, other): ... # x @= y calls x.__imatmul__(y)
... def __itruediv__(self, other): ... # x /= y calls x.__itruediv__(y)
... def __ifloordiv__(self, other): ... # x //= y calls x.__ifloordiv__(y)
... def __imod__(self, other): ... # x %= y calls x.__imod__(y)
6.8.3. Example¶
>>> @dataclass
... class Vector:
... x: int
... y: int
...
... def __iadd__(self, other):
... self.x += other.x
... self.y += other.y
... return self
...
>>>
>>>
>>> a = Vector(x=1, y=2)
>>>
>>> a += Vector(x=10, y=20)
>>> print(a)
Vector(x=11, y=22)
6.8.4. Add vs Iadd¶
>>> @dataclass
... class Vector:
... x: int
... y: int
...
... def __add__(self, other):
... return Vector(
... x = self.x + other.x,
... y = self.y + other.y)
>>>
>>>
>>> a = Vector(x=1, y=2)
>>>
>>> id(a)
4435911632
>>>
>>> a += Vector(x=10, y=20)
>>> id(a)
4435972432
>>>
>>> print(a)
Vector(x=11, y=22)
>>> @dataclass
... class Vector:
... x: int
... y: int
...
... def __iadd__(self, other):
... self.x += other.x
... self.y += other.y
... return self
>>>
>>>
>>> a = Vector(x=1, y=2)
>>>
>>> id(a)
4437201808
>>>
>>> a += Vector(x=10, y=20)
>>> id(a)
4437201808
>>>
>>> print(a)
Vector(x=11, y=22)
6.8.5. Use Case - 0x01¶
Imports:
>>> from dataclasses import dataclass, field
>>> from pprint import pprint
Definition:
>>> @dataclass
... class Astronaut:
... firstname: str
... lastname: str
>>>
>>>
>>> @dataclass
... class Crew:
... members: list[Astronaut] = field(default_factory=list)
...
... def __iadd__(self, other):
... self.members.append(other)
... return self
Usage:
>>> ares3 = Crew()
>>> ares3 += Astronaut('Mark', 'Watney')
>>> ares3 += Astronaut('Melissa', 'Lewis')
>>> pprint(ares3)
Crew(members=[Astronaut(firstname='Mark', lastname='Watney'),
Astronaut(firstname='Melissa', lastname='Lewis')])
>>> for member in ares3.members:
... print(member)
Astronaut(firstname='Mark', lastname='Watney')
Astronaut(firstname='Melissa', lastname='Lewis')
6.8.6. Assignments¶
"""
* Assignment: Operator Increment Add
* Complexity: easy
* Lines of code: 3 lines
* Time: 5 min
English:
1. Overload operator `+=`
2. Make `Astronaut` objects able to add `Missions`, for example:
a. `mark = Astronaut(firstname='Mark', lastname='Watney')`
b. `mark += Mission(2035, 'Ares3')`
c. `mark += Mission(2040, 'Ares5')`
3. Run doctests - all must succeed
Polish:
1. Przeciąż operator `+=`
2. Spraw aby do obiektów klasy `Astronaut` można dodać `Mission`, przykład:
a. `mark = Astronaut(firstname='Mark', lastname='Watney')`
b. `mark += Mission(2035, 'Ares3')`
c. `mark += Mission(2040, 'Ares5')`
3. Uruchom doctesty - wszystkie muszą się powieść
Hints:
* `object.__iadd__() -> self`
Tests:
>>> import sys; sys.tracebacklimit = 0
>>> astro = Astronaut(firstname='Mark', lastname='Watney', missions=[
... Mission(1969, 'Apollo 11'),
... ])
>>> astro += Mission(2024, 'Artemis 3')
>>> astro += Mission(2035, 'Ares 3')
>>> print(astro) # doctest: +NORMALIZE_WHITESPACE
Astronaut(firstname='Mark', lastname='Watney',
missions=[Mission(year=1969, name='Apollo 11'),
Mission(year=2024, name='Artemis 3'),
Mission(year=2035, name='Ares 3')])
"""
from dataclasses import dataclass
@dataclass
class Astronaut:
firstname: str
lastname: str
missions: list
@dataclass
class Mission:
year: int
name: str