我目前正在使用 Python 3.9.1 或 3.8(取决于我使用的设备)
我在 Medium.com 上阅读了一篇关于使用 operator 模块使用字典中的多个键进行排序的文章。我已经实现了一个使用内置丰富比较运算符的类,我想知道是否有办法从一个类中获得相同的功能。我想出了(一种方法)获得单一属性功能:
class Person:
""" The Person class functions as it own representation of a person and base class.
In this video game simulation it functions as the starting point for the Employee
and Customer class but can be adapted to another other operation that deals
with people.
Attributes
----------
_first_name : str
The first name of the person
_middle_name : str
The middle name of the person
_last_name : str
The last name of the person
_dob : datetime.datetime
The property for this will accept a string formatted as "mm.dd.yyyy" and convert it to
a datetime.datetime as well as accepting a datetime.datetime directly
_age : int
This is calculated and assigned a value the date of birth is assigned or changed
_sex : int
For this class 0 is male and 1 is female will build conversion from string representation
_married : bool
Is the person married?
_hair_color : str
Really kind of torn here and would like to pick a color as an RGBA value but for this simulation
sticking with text
_eye_color: str
Same as hair_color
_weight : float
The weight in pounds
_height : float
The height in inches
Methods
-------
"""
# noinspection SpellCheckingInspection
def __init__(self,
fname: str,
mname: str,
lname: str,
dob,
sex,
married,
hair_color,
eye_color,
weight,
height,
sort_by):
self._first_name = fname
self._middle_name = mname
self._last_name = lname
self._dob = None
self._age = 0
self._sex = sex
self._married = married
self._hair_color = hair_color
self._eye_color = eye_color
self._weight = weight
self._height = height
self.dob = dob
self._sort_by = sort_by
self.selection = {
'lastname': self._last_name,
'middlename': self._middle_name,
'firstname': self._first_name,
'dateofbirth': self._dob,
'age': self._age,
'height': self._height,
'weight': self._weight
}
@property
def name(self):
return self._first_name + ' ' + self._last_name
@property
def first_name(self):
return self._first_name
# noinspection SpellCheckingInspection
@first_name.setter
def first_name(self, fname):
self._first_name = fname
@property
def middle_name(self):
return self._middle_name
# noinspection SpellCheckingInspection
@middle_name.setter
def middle_name(self, mname):
self._middle_name = mname
@property
def last_name(self):
return self._last_name
# noinspection SpellCheckingInspection
@last_name.setter
def last_name(self, lname):
self._last_name = lname
@property
def dob(self):
return self._dob
@dob.setter
def dob(self, birth_date):
if isinstance(birth_date, dt.datetime):
self._dob = birth_date
self.set_age(birth_date)
elif isinstance(birth_date, str):
date = re.compile(r'(\d\d).(\d\d).(\d\d\d\d)')
date_result = date.findall(birth_date)
try:
date_tuple = date_result[0]
except IndexError as e:
date_tuple = ()
print(e)
if len(date_tuple) == 3:
month, day, year = date_tuple
self.dob = dt.datetime(int(year), int(month), int(day))
else:
raise ValueError('Date string value not valid must be in the '
'form MM_DD_YYYY where the underscore _ is any'
' character')
else:
raise TypeError(
f'Expected datetime.datetime or string but got {type(birth_date)}'
)
def set_age(self, date_of_birth):
days_delta = dt.datetime.now() - date_of_birth
self._age = int(days_delta.days / 365)
@property
def age(self):
return self._age
@property
def sex(self):
return self._sex
@property
def sort_by(self):
return self._sort_by
# noinspection SpellCheckingInspection
@sort_by.setter
def sort_by(self, key):
# TODO: research a way to transform keys automatically in the dictionary
# by parsing either the docstrings or attribute variables, check out functools
if key in self.selection:
self._sort_by = key
def __lt__(self, other):
if isinstance(other, Person):
if self._sort_by != other._sort_by:
other._sort_by = self._sort_by
if self.selection[self._sort_by] < other.selection[other._sort_by]:
return True
else:
return False
else:
raise TypeError(f'Expected class Person got {type(other)}')
def __le__(self, other):
if isinstance(other, Person):
if self._sort_by != other._sort_by:
other.sort_by = self.sort_by
if self.selection[self._sort_by] <= other.selection[other._sort_by]:
return True
else:
return False
else:
raise TypeError(f'Expected class Person got {type(other)}')
def __eq__(self, other):
if isinstance(other, Person):
if self._sort_by != other._sort_by:
other._sort_by = self._sort_by
if self.selection[self._sort_by] == other.selection[other._sort_by]:
return True
else:
return False
else:
raise TypeError(f'Expected class Person got {type(other)}')
def __gt__(self, other):
if isinstance(other, Person):
if self._sort_by != other._sort_by:
other._sort_by = self._sort_by
if self.selection[self._sort_by] > other.selection[other._sort_by]:
return True
else:
return False
else:
raise TypeError(f'Expected class Person got {type(other)}')
def __ge__(self, other):
if isinstance(other, Person):
if self._sort_by != other._sort_by:
other._sort_by = self._sort_by
if self.selection[self._sort_by] >= other.selection[other._sort_by]:
return True
else:
return False
else:
raise TypeError(f'Expected class Person got {type(other)}')
def __repr__(self):
return f'Person({self._first_name}, {self._middle_name}, ' \
f'{self._last_name}, {self._dob}, {self._age}, ' \
f'{self._sex}, {self._married}, {self._hair_color}, ' \
f'{self._eye_color}, {self._weight}, ' \
f'{self._height}, {self._sort_by})'
def __str__(self):
return f'Name: {self._first_name} {self._middle_name} ' \
f'{self._last_name}\nDate of Birth: {self._dob}\n' \
f'Age: {self._age}\nSex: {self._sex}\nMarried: {self._married}\n' \
f'Hair Color: {self._hair_color}\n' \
f'Eye Color: {self._eye_color}\nWeight: {self._weight}\n' \
f'Height: {self._height}\n)'