class Point(object):
def __init__(self, x, y):
self.x = x
self.y = y
class GoodPoint(object):
__slots__ = ('x', 'y')
def __init__(self, x, y):
self.x = x
self.y = y
for point_type in (Point, GoodPoint):
print('----', point_type)
p = point_type(1, 2)
try:
p.z = 3
except AttributeError as e …
Author | Logan Chien
-
-
Item 17: Slots and Tracemalloc
import tracemalloc class Point(object): def __init__(self, x, y): self.x = x self.y = y class GoodPoint(object): __slots__ = ('x', 'y') def __init__(self, x, y): self.x = x self.y = y def measure_heap(point_type): snapshot1 = tracemalloc.take_snapshot() x = [point_type(i, i) for i in range(1000000)] snapshot2 = tracemalloc …
-
Item 16: Iterate Generator
def iterate_range(start, end): while start < end: yield start start += 1 try: i = iterate_range(3, 5) print(repr(i)) print(repr(iter(i))) while True: print(next(i)) except StopIteration as e: print('Caught:', repr(e))
-
Item 15: Enumerable and iter function
class RangeIterator(object): def __init__(self, start, end): self.i = start self.end = end def __next__(self): if self.i >= self.end: raise StopIteration(self.i) i = self.i self.i += 1 return i class Range(object): def __init__(self, start, end): self.start = start self.end = end def __iter__ …
-
Item 14: Iterator and next Function
class RangeIterator(object): def __init__(self, start, stop): self.i = start self.stop = stop def __next__(self): if self.i >= self.stop: raise StopIteration(self.i) i = self.i self.i += 1 return i i = RangeIterator(3, 5) try: print(next(i, -1)) print(next(i, -1)) print(next(i …
-
Item 13: contextlib.closing()
from contextlib import closing from http.client import HTTPSConnection from urllib.request import urlopen import re patt = re.compile('<h1>[^<]+</h1>') with urlopen('https://example.com') as f: content = f.read().decode('utf-8') print(patt.findall(content)) with closing(HTTPSConnection('example.com')) as conn: conn.request('GET', '/') content = conn.getresponse …
-
Item 12: Nested with Statement
class Resource(object): def __init__(self, id): assert id in (0, 1, 3, 4), "Bad ID" self.id = id def __enter__(self): print('Acquire', self) return self def __exit__(self, exc_type, exc_value, traceback): print('Release', self) def __str__(self): return 'resource_' + str(self.id) for i in range(3): print …
-
Item 11: Context Manager
from contextlib import contextmanager @contextmanager def access_resource(name): print('Acquiring resource:', name) res = [] try: yield res finally: print('Releasing resource:', name, res) with access_resource('To-Do List') as xs: print('Add To-Do Items') xs.append('Item 1') xs.append('Item 2') with access_resource('Finished List') as xs: raise KeyError('Impossible')
-
Item 10: with Statement
class Logger(object): def __init__(self, i): self.msgs = [] self.id = i def __enter__(self): print('BEGIN', self.id) return self.msgs def __exit__(self, exc_type, exc_value, traceback): print('END', self.id, exc_type, exc_value, traceback) for msg in self.msgs: print('NOTE', self.id, msg) return exc_type is ZeroDivisionError for …
-
Item 9: Function Decorator
from functools import wraps def trace(func): @wraps(func) def wrapper(*args, **kwargs): a = ', '.join((repr(x) for x in args)) print(func.__name__ + '(' + a + ')') return func(*args, **kwargs) return wrapper def fac1(n): return 1 if n == 0 else n * fac1(n - 1) fac1 = trace(fac1) @trace def fac2 …