Skip to content

Commit e084708

Browse files
committed
initial
1 parent fa09c74 commit e084708

File tree

3 files changed

+151
-0
lines changed

3 files changed

+151
-0
lines changed

10-interlude_dataclasses.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
def dataclass(cls):
2+
def __init__(self, *args, **kwargs):
3+
for k, v in zip(cls.__annotations__.keys(), args):
4+
setattr(self, k, v)
5+
for k, v in kwargs.items():
6+
if k not in cls.__annotations__:
7+
raise TypeError(
8+
f"__init__() got an unexpected keyword argument '{k}'"
9+
)
10+
setattr(self, k, v)
11+
12+
post_init = getattr(self, '__post_init__', None)
13+
if callable(post_init):
14+
post_init()
15+
16+
def __repr__(self):
17+
kwargs = {k: getattr(self, k) for k in cls.__annotations__}
18+
kwstr = ', '.join([f'{k}={v}' for k, v in kwargs.items()])
19+
return f'{cls.__name__}({kwstr})'
20+
21+
setattr(cls, '__init__', __init__)
22+
setattr(cls, '__repr__', __repr__)
23+
setattr(cls, '__str__', __repr__)
24+
return cls
25+
26+
27+
@dataclass
28+
class Point:
29+
x: int
30+
y: int
31+
32+
def __post_init__(self):
33+
print(' <<<Any further customizaion goes here>>>')

11-dataclasses.py

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
from dataclasses import dataclass
2+
from math import pi
3+
4+
5+
class TypeChecker:
6+
required_type = object
7+
8+
def __init__(self, name=None):
9+
self.name = name
10+
11+
def __get__(self, instance, owner=None):
12+
return instance.__dict__[self.name]
13+
14+
def __set__(self, instance, value):
15+
assert isinstance(value, self.required_type), \
16+
f'Booooo! Expecting a {self.required_type.__name__}'
17+
instance.__dict__[self.name] = value
18+
19+
20+
def typed_dataclass(cls):
21+
cls = dataclass(cls)
22+
23+
for var_name, var_type in cls.__annotations__.items():
24+
class Checker(TypeChecker):
25+
required_type = var_type
26+
27+
setattr(cls, var_name, Checker(var_name))
28+
return cls
29+
30+
31+
@typed_dataclass
32+
class Point:
33+
x: int
34+
y: int
35+
36+
def move_by(self, dx, dy):
37+
self.x += dx
38+
self.y += dy
39+
40+
def __str__(self):
41+
return f'A Point at {self.x}, {self.y}'
42+
43+
44+
@typed_dataclass
45+
class Circle:
46+
center: Point
47+
radius: int
48+
49+
@property
50+
def area(self):
51+
return pi * self.radius ** 2
52+
53+
def __str__(self):
54+
return f'A Circle at {self.center.x}, {self.center.y} and ' + \
55+
f'radius {self.radius}'

12-meta_dataclasses.py

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
from dataclasses import dataclass
2+
from math import pi
3+
4+
5+
class TypeChecker:
6+
required_type = object
7+
8+
def __init__(self, name=None):
9+
self.name = name
10+
11+
def __get__(self, instance, owner=None):
12+
return instance.__dict__[self.name]
13+
14+
def __set__(self, instance, value):
15+
assert isinstance(value, self.required_type), \
16+
f'Booooo! Expecting a {self.required_type.__name__}'
17+
instance.__dict__[self.name] = value
18+
19+
20+
def typed_dataclass(cls):
21+
cls = dataclass(cls)
22+
23+
for var_name, var_type in cls.__annotations__.items():
24+
class Checker(TypeChecker):
25+
required_type = var_type
26+
27+
setattr(cls, var_name, Checker(var_name))
28+
return cls
29+
30+
31+
class TypeCheckMeta(type):
32+
def __new__(meta, name, bases, dct):
33+
cls = super().__new__(meta, name, bases, dct)
34+
return typed_dataclass(cls)
35+
36+
37+
class Base(metaclass=TypeCheckMeta):
38+
__annotations__ = {}
39+
40+
41+
class Point(Base):
42+
x: int
43+
y: int
44+
45+
def move_by(self, dx, dy):
46+
self.x += dx
47+
self.y += dy
48+
49+
def __str__(self):
50+
return f'A Point at {self.x}, {self.y}'
51+
52+
53+
class Circle(Base):
54+
center: Point
55+
radius: int
56+
57+
@property
58+
def area(self):
59+
return pi * self.radius ** 2
60+
61+
def __str__(self):
62+
return f'A Circle at {self.center.x}, {self.center.y} and ' + \
63+
f'radius {self.radius}'

0 commit comments

Comments
 (0)