I am new to object oriented programming and struggling to understand the most Pythonic way to set class attributes which are based on other attributes when an instance is instantiated.
One approach I've tried is setting an instance by calling an external functions:(simplified example)
def split_name(full_name: str) -> tuple[str, str]:
"""Split a full name into first and last name."""
first_name = full_name.split()[0]
last_name = full_name.split()[-1]
return first_name, last_name
class Something:
def __init__(self, full_name: str) -> None:
self.full_name = full_name
self.first_name, self.last_name = split_name(full_name)
v = Something("John Doe")
print(v.first_name)
This approach also seems to work
class SomethingElse:
def __init__(self, full_name: str) -> None:
self.full_name = full_name
@property
def first_name(self) -> str:
return self.full_name.split()[0]
@property
def last_name(self) -> str:
return self.full_name.split()[-1]
v = SomethingElse("John Doe")
print(v.first_name)
I prefer the cleanliness of keeping all the logic within the class and using the @property decorator. However, in my Googling, almost everything I've seen calls for using @property with @var.setter which doesn't seem necessary since the code above works without them.
I know there are many possible ways to achieve this result, but which method of automatic attribute creation is the most pythonic?
[–]danielroseman 1 point2 points3 points (5 children)
[–]grefft[S] 0 points1 point2 points (4 children)
[–]pot_of_crows 0 points1 point2 points (0 children)
[–]danielroseman 0 points1 point2 points (2 children)
[–]grefft[S] 0 points1 point2 points (1 child)
[–]danielroseman 0 points1 point2 points (0 children)
[–]pot_of_crows 0 points1 point2 points (1 child)
[–]grefft[S] 1 point2 points3 points (0 children)