Skip to content

Commit 6179ead

Browse files
committed
add python_decorator.py
1 parent dca203b commit 6179ead

File tree

2 files changed

+194
-2
lines changed

2 files changed

+194
-2
lines changed

README.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# LearnPython
22
以撸代码的形式学习Python, 具体说明在[知乎专栏-撸代码,学知识](https://zhuanlan.zhihu.com/pythoner)
33

4-
============================================================
4+
===============================================================================
55
### python_base.py: 千行代码入门Python
66

77
### python_visual.py: 15张图入门Matplotlib
@@ -19,6 +19,8 @@
1919
### python_requests.py: Python中最好用的爬虫库Requests代码实例
2020

2121
### python_functional.py: Python进阶: 函数式编程实例(附代码)
22-
============================================================
22+
23+
### python_decorator.py: Python进阶: 通过实例详解装饰器(附代码)
24+
===============================================================================
2325

2426
### 您可以fork该项目,并在修改后提交Pull request

python_decorator.py

Lines changed: 190 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,190 @@
1+
# _*_ coding: utf-8 _*_
2+
3+
"""
4+
python_decorator.py by xianhu
5+
"""
6+
7+
import functools
8+
9+
10+
# 构建不太参数的装饰器
11+
def logging(func):
12+
@functools.wraps(func)
13+
def decorator(*args, **kwargs):
14+
print("%s called" % func.__name__)
15+
result = func(*args, **kwargs)
16+
print("%s end" % func.__name__)
17+
return result
18+
return decorator
19+
20+
21+
# 使用装饰器
22+
@logging
23+
def test01(a, b):
24+
print("in function test01, a=%s, b=%s" % (a, b))
25+
return 1
26+
27+
28+
# 使用装饰器
29+
@logging
30+
def test02(a, b, c=1):
31+
print("in function test02, a=%s, b=%s, c=%s" % (a, b, c))
32+
return 1
33+
34+
35+
# 构建带参数的装饰器
36+
def params_chack(*types, **kwtypes):
37+
def _outer(func):
38+
@functools.wraps(func)
39+
def _inner(*args, **kwargs):
40+
result = [isinstance(_param, _type) for _param, _type in zip(args, types)]
41+
assert all(result), "params_chack: invalid parameters"
42+
result = [isinstance(kwargs[_param], kwtypes[_param]) for _param in kwargs if _param in kwtypes]
43+
assert all(result), "params_chack: invalid parameters"
44+
return func(*args, **kwargs)
45+
return _inner
46+
return _outer
47+
48+
49+
# 使用装饰器
50+
@params_chack(int, (list, tuple))
51+
def test03(a, b):
52+
print("in function test03, a=%s, b=%s" % (a, b))
53+
return 1
54+
55+
56+
# 使用装饰器
57+
@params_chack(int, str, c=(int, str))
58+
def test04(a, b, c):
59+
print("in function test04, a=%s, b=%s, c=%s" % (a, b, c))
60+
return 1
61+
62+
63+
# 在类的成员方法中使用装饰器
64+
class ATest(object):
65+
@params_chack(object, int, str)
66+
def test(self, a, b):
67+
print("in function test of ATest, a=%s, b=%s" % (a, b))
68+
return 1
69+
70+
71+
# 同时使用多个装饰器
72+
@logging
73+
@params_chack(int, str, (list, tuple))
74+
def test05(a, b, c):
75+
print("in function test05, a=%s, b=%s, c=%s" % (a, b, c))
76+
return 1
77+
78+
79+
# 构建不带参数的装饰器类
80+
class Decorator(object):
81+
82+
def __init__(self, func):
83+
self.func = func
84+
return
85+
86+
def __call__(self, *args, **kwargs):
87+
print("%s called" % self.func.__name__)
88+
result = self.func(*args, **kwargs)
89+
print("%s end" % self.func.__name__)
90+
return result
91+
92+
93+
# 使用装饰器
94+
@Decorator
95+
def test06(a, b, c):
96+
print("in function test06, a=%s, b=%s, c=%s" % (a, b, c))
97+
return 1
98+
99+
100+
# 构建带参数的装饰器类
101+
class ParamCheck(object):
102+
103+
def __init__(self, *types, **kwtypes):
104+
self.types = types
105+
self.kwtypes = kwtypes
106+
return
107+
108+
def __call__(self, func):
109+
@functools.wraps(func)
110+
def _inner(*args, **kwargs):
111+
result = [isinstance(_param, _type) for _param, _type in zip(args, self.types)]
112+
assert all(result), "params_chack: invalid parameters"
113+
result = [isinstance(kwargs[_param], self.kwtypes[_param]) for _param in kwargs if _param in self.kwtypes]
114+
assert all(result), "params_chack: invalid parameters"
115+
return func(*args, **kwargs)
116+
return _inner
117+
118+
119+
# 使用装饰器
120+
@ParamCheck(int, str, (list, tuple))
121+
def test07(a, b, c):
122+
print("in function test06, a=%s, b=%s, c=%s" % (a, b, c))
123+
return 1
124+
125+
126+
# 装饰器实例: 函数缓存
127+
def funccache(func):
128+
cache = {}
129+
130+
@functools.wraps(func)
131+
def _inner(*args):
132+
if args not in cache:
133+
cache[args] = func(*args)
134+
return cache[args]
135+
return _inner
136+
137+
138+
# 使用装饰器
139+
@funccache
140+
def test08(a, b, c):
141+
# 其他复杂或耗时计算
142+
return a + b + c
143+
144+
145+
# 使用Python自带的装饰器
146+
class People(object):
147+
148+
def __init__(self):
149+
self._name = None
150+
self._age = None
151+
return
152+
153+
@property
154+
def name(self):
155+
return self._name
156+
157+
@name.setter
158+
def name(self, name):
159+
self._name = name
160+
return
161+
162+
@property
163+
def age(self):
164+
return self._age
165+
166+
@age.setter
167+
def age(self, age):
168+
assert 0 < age < 120
169+
self._age = age
170+
return
171+
172+
173+
# 类静态方法和类方法
174+
class A(object):
175+
var = 1
176+
177+
def func(self):
178+
print(self.var)
179+
return
180+
181+
@staticmethod
182+
def static_func():
183+
print(A.var)
184+
return
185+
186+
@classmethod
187+
def class_func(cls):
188+
print(cls.var)
189+
cls().func()
190+
return

0 commit comments

Comments
 (0)