Last active
June 2, 2018 19:21
-
-
Save DadgadCafe/1c4e255ae64e5e81462d2d8ddea49c3f to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# naming conventions: | |
# module_name, package_name, method_name, function_name, global_var_name, instance_var_name, function_parameter_name, local_var_name | |
# ClassName, ExceptionName | |
# GLOBAL_CONSTANT_NAME | |
*a = *range(3), #(1, 2, 3) | |
################# | |
# http://sahandsaba.com/thirty-python-language-features-and-tricks-you-may-not-know.html | |
# 1 Unpacking | |
a, b, c = [1, 2, 3] | |
a, b, c = 1, 2, 3 | |
a, (b, c) = 1, (2, 3) | |
# 2 Unpacking for swapping variables | |
a, b = 1, 2 | |
a, b = b, a | |
# 3 Extended unpacking (Python 3 only) | |
a, *b, c = (1, 2, 3, 4) | |
b # [2, 3] | |
a, *b, c = [1, 2, 3, 4] | |
b # [2, 3] | |
# 4 Negative indexing | |
a = list(range(10)) | |
a[-1] # 9 | |
# 5 List slices (a[start:end]) | |
a = list(range(10)) | |
a[5:] # [5, 6, 7, 8, 9] | |
a[:5] # [0, 1, 2, 3, 4] | |
a[4:7] # [4, 5, 6] | |
# 6 List slices with negative indexing | |
a = list(range(10)) | |
a[-5:] # [5, 6, 7, 8, 9] | |
# 7 List slices with step (a[start:end:step]) | |
a = list(range(10)) | |
a[1:5:2] # [1, 3] | |
a[::2] # [0, 2, 4, 6, 8] | |
# 8 List slices with negative step | |
a = list(range(10)) | |
a[::-2] # [9, 7, 5, 3, 1] | |
# 9 List slice assignment | |
a = list(range(10)) | |
a[5:6] = [0, 0] # substitute | |
a # [0, 1, 2, 3, 4, 0, 0, 6, 7, 8, 9] | |
a[1:1] = [8, 9] # add | |
a #[0, 8, 9, 1, 2, 3, 4, 0, 0, 6, 7, 8, 9] | |
a[1:-1] = [] # remove | |
a # [0, 9] | |
# 10 Naming slices (slice(start, end, step)) | |
a = list(range(10)) | |
s = slice(1, 5, 2) | |
a[s] # [1, 3] | |
# 11 Iterating over list index and value pairs (enumerate) | |
ls = ['one', 'two', 'three'] | |
for i, v in enumerate(ls): | |
print('{}:{}'.format(i, v)) | |
# 12 Iterating over dictionary key and value pairs (dict.iteritems) | |
d = {'a': 1, 'b': 2} | |
for k, v in d.items(): | |
print('{}:{}'.format(k, v)) | |
# 13 Zipping and unzipping lists and iterables | |
l1 = [1, 2, 3] | |
l2 = ['a', 'b', 'c'] | |
z = zip(l1, l2) # [(1, 'a'), (2, 'b'), (3, 'c')] | |
zz = zip(*z) # [(1, 2, 3), ('a', 'b', 'c')] | |
### 14 Grouping adjacent list items using zip | |
a = [1, 2, 3, 4, 5, 6] | |
# Using iterators | |
group_adjacent = lambda a, k: zip(*([iter(a)] * k)) | |
# [iter, iter, iter]; iter points to the same obj | |
group_adjacent(a, 3) | |
# [(1, 2, 3), (4, 5, 6)] | |
group_adjacent(a, 2) | |
# [(1, 2), (3, 4), (5, 6)] | |
group_adjacent(a, 1) | |
# [(1,), (2,), (3,), (4,), (5,), (6,)] | |
# Using slices | |
from itertools import islice | |
group_adjacent = lambda a, k: zip(*(islice(a, i, None, k) for i in range(k))) | |
group_adjacent(a, 3) | |
# [(1, 2, 3), (4, 5, 6)] | |
group_adjacent(a, 2) | |
# [(1, 2), (3, 4), (5, 6)] | |
group_adjacent(a, 1) | |
# [(1,), (2,), (3,), (4,), (5,), (6,)] | |
### 15 Sliding windows (n-grams) using zip and iterators | |
from itertools import islice | |
def n_grams(a, n): | |
z = (islice(a, i, None) for i in range(n)) | |
return zip(*z) | |
a = [1, 2, 3, 4, 5, 6] | |
n_grams(a, 3) | |
# [(1, 2, 3), (2, 3, 4), (3, 4, 5), (4, 5, 6)] | |
n_grams(a, 2) | |
# [(1, 2), (2, 3), (3, 4), (4, 5), (5, 6)] | |
n_grams(a, 4) | |
# [(1, 2, 3, 4), (2, 3, 4, 5), (3, 4, 5, 6)] | |
# 16 Inverting a dictionary using zip | |
m = {'a': 1, 'b': 2, 'c': 3, 'd': 4} | |
dict(zip(m.values(), m.keys())) | |
# 17 Flattening lists: | |
import itertools | |
a = [[1, 2], [3, 4], [5, 6]] | |
list(itertools.chain.from_iterable(a)) | |
sum(a, []) | |
[i for x in a for i in x] | |
# 18 Generator expressions | |
(i for i in range(10)) | |
# 19 Dictionary comprehensions | |
{i: i for i in range(5)} | |
# {0: 0, 1: 1, 2: 2, 3: 3, 4: 4} | |
# 20 Inverting a dictionary using a dictionary comprehension | |
m = {'a': 1, 'b': 2, 'c': 3, 'd': 4} | |
{v:k for k,v in m.items()} | |
# 21 Named tuples (collections.namedtuple) | |
Point = collections.namedtuple('Point', ['x', 'y']) | |
p = Piont(x=1, y=2) | |
p.x | |
# 22 Inheriting from named tuples: | |
class Point(collections.namedtuple('PointBase', ['x', 'y'])): | |
__slots__ = () | |
def __add__(self, other): | |
return Point(x = self.x + other.x, | |
y = self.y + other.y) | |
p1 = Point(x=1, y=2) | |
p2 = Point(x=1, y=2) | |
p3 = p1 + p2 | |
# 23 Sets and set operations | |
s1 = set([1, 2, 3]) | |
s2 = set([2, 3, 4]) | |
s1 & s2 | |
s1 | s2 | |
s1 - s2 | |
s1 ^ s2 # (A ^ B) == ((A - B) | (B - A)) | |
# 24 Multisets and multiset operations (collections.Counter) | |
A = collections.Counter([1, 2, 2]) | |
# Counter({1: 1, 2: 2}) | |
B = collections.Counter([2, 2, 3]) | |
# Counter({2: 2, 3: 1}) | |
A | B | |
A & B | |
A + B | |
A - B | |
# 25 Most common elements in an iterable (collections.Counter) | |
A = collections.Counter([1, 1, 2, 2, 3, 3, 3, 3, 4, 5, 6, 7]) | |
# Counter({1: 2, 2: 2, 3: 4, 4: 1, 5: 1, 6: 1, 7: 1}) | |
A.most_common(1) | |
# [(3, 4)] | |
# 26 Double-ended queue (collections.deque) | |
Q = collections.deque() | |
Q.append(1) | |
Q.appendleft(2) | |
Q.extend([3, 4]) | |
Q.extendleft([5, 6]) | |
Q # deque([6, 5, 2, 1, 3, 4]) | |
Q.pop() | |
Q.popleft() | |
Q.rotate(3) | |
# 27 Double-ended queue with maximum length (collections.deque) | |
last_three = collections.deque(maxlen=3) | |
for i in range(10): | |
last_three.append(i) | |
print(', '.join(str(x) for x in last_three)) | |
# 28 Ordered dictionaries (collections.OrderedDict) | |
m = dict((str(x), x) for x in range(10)) | |
print(', '.join(m.keys())) | |
# 1, 0, 3, 2, 5, 4, 7, 6, 9, 8 | |
m = collections.OrderedDict((str(x), x) for x in range(10)) | |
print(', '.join(m.keys())) | |
# 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 | |
m = collections.OrderedDict((str(x), x) for x in range(10, 0, -1)) | |
print(', '.join(m.keys())) | |
# 10, 9, 8, 7, 6, 5, 4, 3, 2, 1 | |
# 29 Default dictionaries (collections.defaultdict) | |
d = dict() | |
m['a'] # error | |
m = collections.defaultdict(int) | |
m['a'] # 0 | |
m['b'] # 0 | |
m = collections.defaultdict(str) | |
m['a'] # '' | |
m['b'] += 'a' | |
m['b'] # 'a' | |
m = collections.defaultdict(lambda: '[default value]') | |
m['a'] # '[default value]' | |
# 30 Using default dictionaries to represent simple trees | |
import json | |
tree = lambda: collections.defaultdict(tree) | |
root = tree() # f | |
root['menu']['id'] = 'file' | |
root['menu']['value'] = 'File' | |
root['menu']['menuitems']['new']['value'] = 'New' | |
root['menu']['menuitems']['new']['onclick'] = 'new();' | |
root['menu']['menuitems']['open']['value'] = 'Open' | |
root['menu']['menuitems']['open']['onclick'] = 'open();' | |
root['menu']['menuitems']['close']['value'] = 'Close' | |
root['menu']['menuitems']['close']['onclick'] = 'close();' | |
print(json.dumps(root, sort_keys=True, indent=4, separators=(',', ': '))) | |
# 31 Mapping objects to unique counting numbers (collections.defaultdict) | |
import itertools, collections | |
def f(): | |
t = itertools.count() | |
return lambda: next(t) | |
value_to_numeric_map = collections.defaultdict(f()) | |
value_to_numeric_map['a'] # 0 | |
value_to_numeric_map['b'] # 1 | |
value_to_numeric_map['c'] # 2 | |
value_to_numeric_map['a'] # 0 | |
value_to_numeric_map['b'] # 1 | |
# 32 Largest and smallest elements (heapq.nlargest and heapq.nsmallest) | |
[random.randint(0, 100) for _ in range(100)] | |
heapq.nsmallest(5, a) | |
heapq.nlargest(5, a) | |
# 33 Cartesian products (itertools.product) | |
# 34 Combinations and combinations with replacement (itertools.combinations and itertools.combinations_with_replacement) | |
for c in itertools.combinations([1, 2, 3, 4, 5], 3): | |
print(''.join(str(x) for x in c)) | |
for c in itertools.combinations_with_replacement([1, 2, 3], 2): | |
print(''.join(str(x) for x in c)) | |
# 35 Permutations (itertools.permutations) | |
for p in itertools.permutations([1, 2, 3, 4]): | |
print(''.join(str(x) for x in p)) | |
# 36 Chaining iterables (itertools.chain) | |
a = [1, 2, 3, 4] | |
for p in itertools.chain(itertools.combinations(a, 2), | |
itertools.combinations(a, 3)): | |
print(p) | |
# 37 Grouping rows by a given key (itertools.groupby) | |
# 38 Start a static HTTP server in any directory | |
# python -m SimpleHTTPServer 5000 | |
# 39 Learn the Zen of Python | |
import this | |
# 40 Use C-Style Braces Instead of Indentation to Denote Scopes | |
from __future__ import braces | |
#!/usr/bin/env python3 | |
# -*- coding: utf-8 -*- | |
# # octothrope, pound character | |
ord('A') # 65 | |
chr(65) # 'A' | |
print('%d' % 123) | |
print('%r' % False) # %r for debugging | |
print('%s' % False) | |
print('%s' % '123') | |
# array append insert pop | |
# dict | |
dt = {'a': 1, 'b': 2} | |
dt.get('a', 'default') | |
dt['a'] | |
if 'a' in dt | |
dt.pop('a') | |
# set | |
st = {1, 2, 3} | |
st2 = set([3, 4, 5]) | |
st & st2 | |
st | st2 | |
st.add(5) | |
st.remove(5) | |
# func | |
def person(name, age, *, city='Beijing', job): | |
print(name, age, city, job) | |
def f(*args, **kwargs): | |
print(args, kwargs) | |
f(1, 2, a=3, b=4) | |
f(*[1], **{'a':1}) | |
# slice | |
ls = [1, 2, 3] | |
ls[1:] # [2, 3] | |
ls[:2] # [1, 2] | |
ls[1:2] # [2a] | |
ls[:-1] # [1, 2] | |
L = list(range(10)) | |
# copy list | |
ls[:] | |
L[:5:2] # [0, 2, 4] | |
L[::5] # [0, 5] | |
## iteration | |
for k in dict | |
print(k) | |
for v in dict.values() | |
print(v) | |
for k, v in dict.items() | |
print(k, v) | |
from collections import Iterable | |
isinstance('abc', Iterable) # True | |
for (i, v) in enumerate([1, 2, 3]): | |
print(i, v) | |
for (a, b) in [(1, 2), (3, 4)]: | |
print(a, b) | |
## list comprehension | |
[x*y for x in range(5) for y in range(5)] | |
## generator | |
(x*y for x in range(5) for y in range(5)) | |
def g(max): | |
i = 0 | |
while i <= max: | |
yield i | |
i += 1 | |
return 'DONE' | |
g5 = g(5) | |
while True: | |
try: | |
ret = next(g5) | |
print(ret) | |
except StopIteration as e: | |
print(e.value) | |
break | |
## diff Iterable Iterator | |
iter([1, 2, 3]) # Iterable to Iterator | |
## HOF | |
def f(): | |
a = 5 | |
def ff(): | |
nonlocal a | |
a += 1 | |
print(a) | |
ff() | |
print(a) | |
## functools partial | |
import functools | |
int2 = functools.partial(int, base=2) | |
## module | |
# pkg | |
# __init__.py | |
# xx.py | |
# yy.py | |
import pkg | |
import pkg.xx | |
## class | |
class Animal(): | |
def __init__(self, name): | |
self.name = name | |
class Dog(Animal): | |
def __init__(self, name): | |
super().__init__(name) | |
# super(self.__class__, self).__init__(name) | |
# Animal.__init__(self, name) | |
hasattr() | |
getattr() | |
# slots | |
class Student(object): | |
__slots__ = ('name', 'age') | |
# getter setter @property decorator | |
class Student(object): | |
def __init__(self, score): | |
self.__score = score | |
@property | |
def score(self): | |
return self.__score | |
@score.setter | |
def score(self, value): | |
if not isinstance(value, int): | |
raise ValueError('score must be an integer!') | |
if value < 0 or value > 100: | |
raise ValueError('score must between 0 ~ 100!') | |
self.__score = value | |
__str__ | |
__repr__ | |
__iter__ | |
__next__ | |
__getitem__ | |
__getattr__ | |
__call__ | |
def Fib(): | |
def __init__(self): | |
self.a = 0 | |
self.b = 1 | |
def __iter__(self): | |
return self | |
def __next__(self): | |
self.a, self.b = self.b, self.a + self.b | |
if self.a > 10000: | |
raise StopIteration() | |
else: | |
return self.a | |
def __getitem__(self, n): | |
if isinstance(n, int): # n是索引 | |
a, b = 1, 1 | |
for x in range(n): | |
a, b = b, a + b | |
return a | |
if isinstance(n, slice): # n是切片 | |
start = n.start | |
stop = n.stop | |
if start is None: | |
start = 0 | |
a, b = 1, 1 | |
L = [] | |
for x in range(stop): | |
if x >= start: | |
L.append(a) | |
a, b = b, a + b | |
return L | |
class Chain(object): | |
def __init__(self, path=''): | |
self._path = path | |
def __getattr__(self, path): | |
return Chain('%s/%s' % (self._path, path)) | |
def __str__(self): | |
return self._path | |
__repr__ = __str__ | |
Chain().status.user.timeline.list # '/status/user/timeline/list' | |
# enum | |
from enum import Enum | |
Month = Enum('Month', ('Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec')) | |
for name, member in Month.__members__.items(): | |
print(name, '=>', member, ',', member.value) | |
from enum import Enum, unique | |
@unique | |
class Weekday(Enum): | |
Sun = 0 # Sun的value被设定为0 | |
Mon = 1 | |
Tue = 2 | |
Wed = 3 | |
Thu = 4 | |
Fri = 5 | |
Sat = 6 | |
# type | |
# 动态创建 class; 实际上,class 也是通过 type 创建 | |
def fn(self, name='non'): | |
print(name) | |
C = type('C', (object,), dict(fn=fn)) # name; tuple of superclass; dict of attrs | |
c = C() | |
c.fn() | |
# metaclass usage:ORM | |
# metaclass是类的模板,所以必须从`type`类型派生: | |
class ListMetaclass(type): | |
def __new__(cls, name, bases, attrs): # 当前准备创建的类的对象; 类的名字; 类继承的父类集合; 类的方法集合 | |
attrs['add'] = lambda self, value: self.append(value) | |
return type.__new__(cls, name, bases, attrs) | |
class MyList(list, metaclass=ListMetaclass): | |
pass | |
L = MyList() | |
L.add(1) | |
## with | |
class WithClass: | |
def __init__(self): | |
print('__init__') | |
def __enter__(self): | |
print('__enter__') | |
def __exit__(self, exe_type, exe_value, traceback): | |
print('__exit__') | |
print(exe_type) | |
print(exe_value) | |
print(traceback) | |
return True # supress exception | |
def __repr__(self): | |
print('with class obj') | |
with WithClass() as o: | |
print(f'do something with {o}') | |
raise Exception('error occurs') | |
print('all done') | |
from contextlib import contextmanager | |
@contextmanager | |
def manage_file(): | |
try: | |
print('__enter__') | |
yield | |
finally: | |
print('__exit__') | |
@contextmanager | |
def manage_file(name): | |
try: | |
f = open(name) | |
yield f | |
finally: | |
f.close() | |
with manage_file('test.txt') as f: | |
f.read() | |
## io | |
with open('/path/to/file', 'r') as f: | |
print(f.read()) | |
try: | |
f = open('/..', r) | |
print(f.read()) | |
finally: | |
if f: | |
f.close() | |
for line in f.readlines(): | |
print(line.strip()) | |
f = open('/Users/michael/test.txt', 'w') | |
f.write('Hello, world!') | |
f.close() | |
with open('/Users/michael/test.txt', 'w') as f: | |
f.write('Hello, world!') | |
f.read() # blabla.. | |
f.read() # nothing... cursor at end.. | |
f.seek(0) # move cursor back to 0 | |
f.read() # blabla | |
f.tell() # where is cursor | |
f.readline() # read a line, cursor to next line | |
f.readlines() # read all line, store to array | |
# pickle | |
import pickle | |
f = open('dump.txt', 'wb') | |
pickle.dump('teststests', f) | |
f.close() | |
f = open('dump.txt', 'rb') | |
d = pickle.load(f) | |
f.close() | |
with open('dump.txt', 'wb') as f: | |
pickle.dump(d, f) | |
# json | |
import json | |
d = dict(name='Bob', age=20, score=88) | |
json.dumps(d) # '{"age": 20, "score": 88, "name": "Bob"}' | |
json_str = '{"age": 20, "score": 88, "name": "Bob"}' | |
d = json.loads(json_str) # {'age': 20, 'score': 88, 'name': 'Bob'} | |
# dump class to json format | |
json.dumps(s, default=lambda obj: obj.__dict__) | |
json.loads(json_str, object_hook=lambda d: Cls(**d)) | |
## misc | |
import types | |
types.FunctionType #... | |
import sys | |
sys.path # view system path | |
sys.path.append('/Users/michael/my_py_scripts')# 运行时修改路径 | |
"." * 10 | |
a, b, c = [1, 2, 3] | |
d, e, f = (4, 5, 6) | |
from sys import argv | |
a, b, c, d = argv | |
def id(*all): | |
return all #tuple | |
## generic function | |
class C(object): | |
def foo(self): | |
pass | |
C().foo # bound | |
C.foo # unbound | |
C.__dict__['foo'].__get__(None, C) | |
C.__dict__['foo'].__get__(c, C) | |
# namedtulpe <= tuple | |
# magic method | |
## def func | |
class People(object): | |
'''Silly Person''' | |
## ??? not working in py3, | |
## refact print in decorator | |
def __new__(cls, *args, **kwargs): | |
print('__new__ called.') | |
return super(People, cls).__new__(cls, *args, **kwargs) | |
def __init__(self, name, age): | |
print('__init__ called.') | |
self.name = name | |
self.age = age | |
def __str__(self): | |
return 'PERSON: %s %s' % (self.name, self.age) | |
## decorator | |
import functools | |
def log(func): | |
@functools.wraps(func) | |
def wrapper(*args, **kw): | |
print('before %s():' % func.__name__) | |
ret = func(*args, **kw) | |
print('after %s():' % func.__name__) | |
return ret | |
return wrapper | |
# custom decorator log; works with @log and @log('DEBUG') | |
def log(mode): | |
def log(func): | |
@functools.wraps(func) | |
def wrapper(*args, **kw): | |
print('%s: before %s():' % mode func.__name__) | |
ret = func(*args, **kw) | |
print('%s: after %s():' % mode func.__name__) | |
return ret | |
return wrapper | |
if isinstance(mode, str): | |
return log | |
else: | |
fn = mode | |
mode = 'DEFAULT' | |
return log(fn) | |
class P(): | |
'''Silly Person''' | |
@log | |
def __f(self): | |
pass | |
@staticmethod | |
@log | |
def __F(): | |
pass | |
@log | |
def f(self): | |
self.__f() | |
# self.__F() | |
P.__F() | |
@log | |
def __init__(self): | |
pass | |
#################### | |
class PositiveInteger(int): | |
def __init__(self, value): | |
super(PositiveInteger, self).__init__(self, abs(value)) | |
i = PositiveInteger(-3) | |
print i | |
=> | |
class PositiveInteger(int): | |
def __new__(cls, value): | |
return super(PositiveInteger, cls).__new__(cls, abs(value)) | |
i = PositiveInteger(-3) | |
print i | |
## 实现单例模式 | |
class Singleton(object): | |
def __new__(cls): | |
# 关键在于这,每一次实例化的时候,我们都只会返回这同一个instance对象 | |
if not hasattr(cls, 'instance'): | |
cls.instance = super(Singleton, cls).__new__(cls) | |
return cls.instance | |
obj1 = Singleton() | |
obj2 = Singleton() | |
obj1.attr1 = 'value1' | |
print obj1.attr1, obj2.attr1 | |
print obj1 is obj2 | |
######### | |
class Movie(object): | |
def __init__(self, title, description, score): | |
self.title = title | |
self.description = description | |
self.score = score | |
self.ticket = ticket | |
@property | |
def score(self): | |
return self.__score | |
@score.setter | |
def score(self, score): | |
if score < 0: | |
raise ValueError("Negative value not allowed:{}".format(score)) | |
self.__score = score | |
@score.deleter | |
def score(self): | |
raise AttributeError("Can not delete score") | |
=> | |
class Integer(object): | |
def __init__(self, name): | |
self.name = name | |
def __get__(self, instance, owner): | |
return instance.__dict__[self.name] | |
def __set__(self, instance, value): | |
if value < 0: | |
raise ValueError("Negative value not allowed") | |
instance.__dict__[self.name] = value | |
class Movie(object): | |
score = Integer('score') | |
ticket = Integer('ticket') | |
=> | |
class Integer(object): | |
def __init__(self, name): | |
self.name = name | |
def __get__(self, instance, owner): | |
if instance is None: | |
return self | |
return instance.__dict__[self.name] | |
def __set__(self, instance, value): | |
if value < 0: | |
raise ValueError('Negative value not allowed') | |
instance.__dict__[self.name] = value | |
class Movie(object): | |
score = Integer('score') | |
ticket = Integer('ticket') | |
def __init__(self, title, description, score, ticket): | |
self.title = title | |
self.description = description | |
self.score = score | |
self.ticket = ticket | |
############# | |
from collections import Counter | |
l = ['a', 'b', 'c', 'a'] | |
Counter(l) | |
############# | |
import collections | |
Card = collections.namedtuple('Card', ['rank', 'suit']) | |
class FrenchDeck(): | |
ranks = [str(n) for n in range(2, 11)] + list('JQKA') | |
suits = 'spades diamonds clubs hearts'.split() | |
def __init__(self): | |
self._cards = [Card(rank, suit) for rank in self.ranks | |
suit in self.suits] | |
def __len__(self): | |
return len(self.cards) | |
def __getitem__(self, position): | |
return self._cards[position] | |
deck = FrenchDeck() | |
len(deck) | |
deck[0] | |
decl[-1] | |
from random import choice | |
choice(deck) | |
## asyncio | |
import asyncio | |
@asyncio.coroutine | |
def hello(): | |
print('hello ') | |
r = yield from asyncio.sleep(1) | |
print('world') | |
# async await | |
async def hello(): | |
print("Hello world!") | |
r = await asyncio.sleep(1) | |
print("Hello again!") | |
loop = asyncio.get_event_loop() | |
loop.run_until_complete(hello()) | |
loop.close() | |
import threading | |
import asyncio | |
@asyncio.coroutine | |
def hello(): | |
print('Hello world! (%s)' % threading.currentThread()) | |
yield from asyncio.sleep(1) | |
print('Hello again! (%s)' % threading.currentThread()) | |
loop = asyncio.get_event_loop() | |
tasks = [hello(), hello()] | |
loop.run_until_complete(asyncio.wait(tasks)) | |
loop.close() | |
import asyncio | |
@asyncio.coroutine | |
def wget(host): | |
print('wget %s...' % host) | |
connect = asyncio.open_connection(host, 80) | |
reader, writer = yield from connect | |
header = 'GET / HTTP/1.0\r\nHost: %s\r\n\r\n' % host | |
writer.write(header.encode('utf-8')) | |
yield from writer.drain() | |
while True: | |
line = yield from reader.readline() | |
if line == b'\r\n': | |
break | |
print('%s header > %s' % (host, line.decode('utf-8').rstrip())) | |
# Ignore the body, close the socket | |
writer.close() | |
async def wget(host): | |
print('wget %s...' % host) | |
connect = asyncio.open_connection(host, 80) | |
reader, writer = await connect | |
header = 'GET / HTTP/1.0\r\nHost: %s\r\n\r\n' % host | |
writer.write(header.encode('utf-8')) | |
await writer.drain() | |
while True: | |
line = await reader.readline() | |
if line == b'\r\n': | |
break | |
print('%s header > %s' % (host, line.decode('utf-8').rstrip())) | |
# Ignore the body, close the socket | |
writer.close() | |
loop = asyncio.get_event_loop() | |
tasks = [wget(host) for host in ['www.sina.com.cn', 'www.sohu.com', 'www.163.com']] | |
loop.run_until_complete(asyncio.wait(tasks)) | |
loop.close() | |
import threading | |
from functools import wraps | |
def delay(delay = 0): | |
''' | |
Decorator delaying the execution of a function for a while. | |
''' | |
def wrap(f): | |
@wraps(f) | |
def delayed(*args, **kwargs): | |
timer = threading.Timer(delay, f, args=args, kwargs=kwargs) | |
timer.start() | |
return delayed | |
return wrap | |
from utils import delay | |
@delay(3) | |
def my_func(*args): | |
print(args) | |
if __name__ == '__main__': | |
my_func('Hello', 'world') | |
type('Bar', (object,), {'spam': 'eggs'}) | |
class MetaClass(type): | |
def __init__(cls, name, bases, attrs): | |
print('Defining %s' % cls) | |
print('Name: %s' % name) | |
print('Bases: %s' % (bases,)) | |
print('Attributes:') | |
for (name, value) in attrs.items(): | |
print(' %s: %r' % (name, value)) | |
class RealClass(object, metaclass=MetaClass): | |
spam = 'eggs' | |
class SubClass(RealClass): # Notice there's no metaclass here. | |
pass | |
class Multipler(): | |
def __init__(self, n): | |
self.n = n | |
def __call__(self, m): | |
return self.n * m | |
def multiple(n): | |
return lambda m: m*n | |
class FakeDict(): | |
def __init__(self): | |
# prevent setattr | |
self.__dict__['_d'] = {} | |
# intercept . | |
def __getattr__(self, k): | |
print('accessing getattr', k) | |
if k in self._d: | |
return self._d[k] | |
# intercept . assign value | |
def __setattr__(self, k, v): | |
print('accessing setattr', k, v) | |
self._d[k] = v | |
# in | |
def __contains__(self, k): | |
print('accessing contain', k) | |
return k in self._d | |
# intercept [] | |
def __getitem__(self, k): | |
print('accessing getitem', k) | |
if k in self._d: | |
return self._d[k] | |
return None | |
# intercept [] assign value | |
def __setitem__(self, k, v): | |
print('accessing setitem', k, v) | |
self._d[k] = v | |
d = FakeDict() | |
d.a = 5 #accessing setattr a 5 | |
d.a #accessing getattr a 5 | |
d['a'] #accessing getitem a 5 | |
d['a'] = 10 #accessing setitem a 10 | |
d.a | |
d.__dict__ #{'_d': {'a': 10}} | |
class C(): | |
def __init__(self): | |
pass | |
def f(self): | |
print('self f') | |
def f(): | |
print('f') | |
@staticmethod | |
def f(): | |
print('static f') | |
C().f() # staic => f => self | |
class C(): | |
a = 4 | |
def __init__(self): | |
self.a = 5 | |
C().f() # call C.f then c.f | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment