Open rusu24edward opened 3 years ago
Should also consider using decorators for the setters in state components, like so:
class Circle:
def __init__(self, radius):
self._radius = radius
@property
def radius(self):
"""Get value of radius"""
return self._radius
@radius.setter
def radius(self, value):
"""Set radius, raise error if negative"""
if value >= 0:
self._radius = value
else:
raise ValueError("Radius must be positive")
@property
def area(self):
"""Calculate area inside circle"""
return self.pi() * self.radius**2
def cylinder_volume(self, height):
"""Calculate volume of cylinder with circle as base"""
return self.area * height
@classmethod
def unit_circle(cls):
"""Factory method creating a circle with radius 1"""
return cls(1)
@staticmethod
def pi():
"""Value of π, could use math.pi instead though"""
return 3.1415926535
>>> c = Circle(5)
>>> c.radius
5
>>> c.area
78.5398163375
>>> c.radius = 2
>>> c.area
12.566370614
>>> c.area = 100
AttributeError: can't set attribute
>>> c.cylinder_volume(height=4)
50.265482456
>>> c.radius = -1
ValueError: Radius must be positive
>>> c = Circle.unit_circle()
>>> c.radius
1
>>> c.pi()
3.1415926535
>>> Circle.pi()
3.1415926535
The default dataclass decorator is not intelligent enough to handle additional logic in the properties. For example, setting a min/max value, reserving some values and unusable, etc. This may be good to use in some cases, but cannot be used in every definition.
This article is a way to reconcile the two, but you're not saving much at this point...
from dataclasses import dataclass, field
@dataclass
class Vehicle:
wheels: int
_wheels: int = field(init=False, repr=False)
@property
def wheels(self) -> int:
print("getting wheels")
return self._wheels
@wheels.setter
def wheels(self, wheels: int):
print("setting wheels to", wheels)
self._wheels = wheels
Agent classes are really just dictionaries, and they're all pretty much the same. We should modify the dataclass decorator to give agents a configured function automatically and use this decorator everywhere we define an Agent to save from writing so much boilerplate code.
In epic #12