0%

python-第三天学习

python3基础学习

装饰器

装饰器原来感觉不好理解,这不就是函数嘛,为啥叫装饰器,在知乎上看到的解释还蛮不错的,就是原来有个东西,只有基础的部件,通过添加一些新东西过后,他就变成一个高级的部件

题目练习:请编写一个 decorator,能在函数调用的前后打印出’begin call’和’end call’的日志

1
2
3
4
5
6
7
def log(func):
@functools.wraps(func)
def wrapper(*args,**kw):
print "call start"
func(*args,**kw)
print "call end"
return wrapper

思考题:再思考一下能否写出一个@log的decorator,使它既支持:

1
2
3
4
5
6
7
@log
def f():
pass
又支持:
@log('execute')
def f():
pass

经过测试,是不可以的,先贴上我的代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
def log(text = 'execute'):
def decorator(func):
@functools.wraps(func)
def wrapper(*args,**kw):
func(*args,**kw)
return wrapper
return decorator

@log('execute')
#@log
def now(a,b):
print "a+b is :{},{}".format(a+b,a-b)

now(1,2)

理由如下:

我以为利用默认参数可以,可报错出现了,显示的是decorator take exactly 1 arguements(2 given) 仔细分析一下可以知道@log(‘execute’)是执行完最外层的return了,到了decorator这层,这次就是now = decorator(now),而如果我用@log的话,就是now = log(now),这样明显会出错,无法将函数传到第二层的装饰器部分,即使有默认参数,他也只将now当作你传入的参数,也就是text进行执行,然后这样执行下来的结果就变成decorator(1,2)错误的做法

练习题:请利用@property 给一个 Screen 对象加上width和height属性,以及一个只读属性 resolution

1
2
3
4
5
6
7
8
9
10
class Screen(object):
----
pass
----
# test:
s = Screen()
s.width = 1024
s.height = 768
print(s.resolution)
assert s.resolution == 786432, '1024 * 768 = %d ?' % s.resolution
  • 类这大部分跟c的差别不大,唯一的区别就是可以动态绑定属性和函数
  • 这道题不难,很简单,就是方法的使用,无技巧性的东西
  • 贴上我的代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class Screen(object):
@property
def width(self):
return self._width
@width.setter
def width(self,value):
self._birth = value
@property
def height(self):
return self._height
@height.setter
def height(self,value):
self._height = value
@property
def resolution(self):
return self._birth * self._height

s = Screen()
s.width = 1024
s.height = 768
print (s.resolution)
assert s.resolution == 786432, '1024 * 768 = {}'.format(s.resolution)

本文作者:NoOne
本文地址https://noonegroup.xyz/posts/a6467bc7/
版权声明:转载请注明出处!