-
Notifications
You must be signed in to change notification settings - Fork 5.3k
/
Copy pathperson.py
107 lines (82 loc) · 3.04 KB
/
person.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
import copy
from datetime import date
def in_place():
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
def __replace__(self, **changes):
if unknown := changes.keys() - self.__dict__.keys():
raise AttributeError(", ".join(unknown))
self.__dict__.update(**changes)
person = Person("John Doe", 42)
copy.replace(person, age=24, name="Alice Smith")
print(vars(person))
# This raises an error:
# print(copy.replace(person, name="Bob Brown", email="bob.brown@example.com"))
def shallow():
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
def __replace__(self, **changes):
return type(self)(**self.__dict__ | changes)
person = Person("John Doe", 42)
person_copy = copy.replace(person, age=24, name="Alice Smith")
print(vars(person))
print(vars(person_copy))
# This raises an error:
# print(copy.replace(person, email="bob.brown@example.com"))
def slots():
class Person:
__slots__ = ("name", "age")
def __init__(self, name, age):
self.name = name
self.age = age
def __replace__(self, **changes):
instance = type(self)(self.name, self.age)
for name, value in changes.items():
if hasattr(self, name):
setattr(instance, name, value)
return instance
person = Person("John Doe", 42)
person_copy = copy.replace(person, age=24, name="Alice Smith")
def vars_slots(obj):
return {name: getattr(obj, name) for name in obj.__slots__}
print(vars_slots(person))
print(vars_slots(person_copy))
def derived():
class Person:
def __init__(self, name, date_of_birth):
self.name = name
self.date_of_birth = date_of_birth
@property
def age(self):
return (date.today() - self.date_of_birth).days // 365
def __replace__(self, **changes):
age = changes.pop("age", None)
dob = changes.pop("date_of_birth", None)
instance = copy.copy(self)
for name, value in changes.items():
if hasattr(self, name):
setattr(instance, name, value)
if age and dob:
raise AttributeError(
"can't set both 'age' and 'date_of_birth'"
)
elif age:
dob = copy.replace(date.today(), year=date.today().year - age)
instance.date_of_birth = dob
elif dob:
instance.date_of_birth = dob
return instance
person = Person("John Doe", date(1983, 3, 14))
print(vars(copy.replace(person, age=24)))
print(vars(copy.replace(person, date_of_birth=date(1999, 6, 15))))
# This raises an error:
# print(vars(copy.replace(person, date_of_birth=date(1999, 6, 15), age=12)))
if __name__ == "__main__":
in_place()
shallow()
slots()
derived()