Skip to content

Commit c3559e2

Browse files
committed
chapter 18
1 parent 5561b38 commit c3559e2

File tree

2 files changed

+131
-0
lines changed

2 files changed

+131
-0
lines changed

Chapter18/prototype.py

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
import copy
2+
3+
class Website:
4+
def __init__(self, name, domain, description, author, **kwargs):
5+
'''Examples of optional attributes (kwargs):
6+
category, creation_date, technologies, keywords.
7+
'''
8+
self.name = name
9+
self.domain = domain
10+
self.description = description
11+
self.author = author
12+
13+
for key in kwargs:
14+
setattr(self, key, kwargs[key])
15+
16+
def __str__(self):
17+
summary = [f'Website "{self.name}"\n',]
18+
19+
infos = vars(self).items()
20+
ordered_infos = sorted(infos)
21+
for attr, val in ordered_infos:
22+
if attr == 'name':
23+
continue
24+
summary.append(f'{attr}: {val}\n')
25+
26+
return ''.join(summary)
27+
28+
29+
class Prototype:
30+
def __init__(self):
31+
self.objects = dict()
32+
33+
def register(self, identifier, obj):
34+
self.objects[identifier] = obj
35+
36+
def unregister(self, identifier):
37+
del self.objects[identifier]
38+
39+
def clone(self, identifier, **attrs):
40+
found = self.objects.get(identifier)
41+
if not found:
42+
raise ValueError(f'Incorrect object identifier: {identifier}')
43+
obj = copy.deepcopy(found)
44+
for key in attrs:
45+
setattr(obj, key, attrs[key])
46+
47+
return obj
48+
49+
def main():
50+
keywords = ('python', 'data', 'apis', 'automation')
51+
site1 = Website('ContentGardening',
52+
domain='contentgardening.com',
53+
description='Automation and data-driven apps',
54+
author='Kamon Ayeva',
55+
category='Blog',
56+
keywords=keywords)
57+
58+
prototype = Prototype()
59+
identifier = 'ka-cg-1'
60+
prototype.register(identifier, site1)
61+
62+
site2 = prototype.clone(identifier,
63+
name='ContentGardeningPlayground',
64+
domain='play.contentgardening.com',
65+
description='Experimentation for techniques featured on the blog',
66+
category='Membership site',
67+
creation_date='2018-08-01')
68+
69+
for site in (site1, site2):
70+
print(site)
71+
print(f'ID site1 : {id(site1)} != ID site2 : {id(site2)}')
72+
73+
if __name__ == '__main__':
74+
main()
75+

Chapter18/singleton.py

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
2+
3+
import urllib.parse
4+
import urllib.request
5+
6+
7+
class SingletonType(type):
8+
_instances = {}
9+
def __call__(cls, *args, **kwargs):
10+
if cls not in cls._instances:
11+
cls._instances[cls] = super(SingletonType, cls).__call__(*args, **kwargs)
12+
return cls._instances[cls]
13+
14+
15+
class URLFetcher(metaclass=SingletonType):
16+
17+
def __init__(self):
18+
self.urls = []
19+
20+
def fetch(self, url):
21+
req = urllib.request.Request(url)
22+
with urllib.request.urlopen(req) as response:
23+
if response.code == 200:
24+
the_page = response.read()
25+
print(the_page)
26+
27+
urls = self.urls
28+
urls.append(url)
29+
self.urls = urls
30+
31+
def dump_url_registry(self):
32+
return ', '.join(self.urls)
33+
34+
35+
def main():
36+
37+
MY_URLS = ['http://google.com',
38+
'http://python.org',
39+
'https://www.python.org/error',
40+
]
41+
42+
print(URLFetcher() is URLFetcher())
43+
44+
fetcher = URLFetcher()
45+
for url in MY_URLS:
46+
try:
47+
fetcher.fetch(url)
48+
except Exception as e:
49+
print(e)
50+
51+
print('-------')
52+
done_urls = fetcher.dump_url_registry()
53+
print(f'Done URLs: {done_urls}')
54+
55+
if __name__ == '__main__':
56+
main()

0 commit comments

Comments
 (0)