【python】装饰器!property和setter用法

网友投稿 522 2022-05-30

文章目录

1.引子:函数也是对象

2.函数内的函数

3.装饰器小栗子

5.property和setter用法

reference

1.引子:函数也是对象

木有括号的函数那就不是在调用。

def hi(name="yasoob"): return "hi " + name print(hi()) # output: 'hi yasoob' # 我们甚至可以将一个函数赋值给一个变量,比如 greet = hi # 我们这里没有在使用小括号,因为我们并不是在调用hi函数 # 而是在将它放在greet变量里头。我们尝试运行下这个 print(greet()) # output: 'hi yasoob' # 如果我们删掉旧的hi函数,看看会发生什么! del hi print(hi()) #outputs: NameError print(greet()) #outputs: 'hi yasoob'

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

2.函数内的函数

(1)在python中,一个函数内能嵌套定义另一个函数,并且可以在该大函数内调用该小函数。

def hi(name="yasoob"): print("now you are inside the hi() function") def greet(): return "now you are in the greet() function" def welcome(): return "now you are in the welcome() function" print(greet()) print(welcome()) print("now you are back in the hi() function") hi() #output:now you are inside the hi() function # now you are in the greet() function # now you are in the welcome() function # now you are back in the hi() function # 上面展示了无论何时你调用hi(), greet()和welcome()将会同时被调用。 # 然后greet()和welcome()函数在hi()函数之外是不能访问的,比如: greet() #outputs: NameError: name 'greet' is not defined

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

(2)开始神奇的是,大函数的返回值可以是一个函数:

def hi(name="yasoob"): def greet(): return "now you are in the greet() function" def welcome(): return "now you are in the welcome() function" if name == "yasoob": return greet #这里!! else: return welcome a = hi() print(a) #outputs: #上面清晰地展示了`a`现在指向到hi()函数中的greet()函数 #现在试试这个 print(a()) #outputs: now you are in the greet() function

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

在 if/else 语句中我们返回 greet 和 welcome,而不是 greet() 和 welcome()。

为什么那样?这是因为

当你把一对小括号放在后面,这个函数就会执行;然而如果你不放括号在它后面,那它可以被到处传递,并且可以赋值给别的变量而不去执行它

当我们写下 a = hi(),hi() 会被执行,而由于 name 参数默认是 yasoob,所以函数 greet 被返回了。

PS:如果我们打印出 hi()(),这会输出 now you are in the greet() function。

(3)最后要说的是函数作为参数传入一个函数:

def hi(): return "hi yasoob!" def doSomethingBeforeHi(func): print("I am doing some boring work before executing hi()") print(func()) doSomethingBeforeHi(hi) #outputs:I am doing some boring work before executing hi() # hi yasoob!

1

2

3

4

5

6

7

8

9

10

3.装饰器小栗子

终于来到了带@的装饰器,其实就是

带了@帽子的函数作为参数,传入@后面的函数中

def a_new_decorator(a_func): def wrapTheFunction(): print("I am doing some boring work before executing a_func()") a_func() print("I am doing some boring work after executing a_func()") return wrapTheFunction @a_new_decorator def a_function_requiring_decoration(): """Hey you! Decorate me!""" print("I am the function which needs some decoration to " "remove my foul smell") a_function_requiring_decoration() #outputs: I am doing some boring work before executing a_func() # I am the function which needs some decoration to remove my foul smell # I am doing some boring work after executing a_func() #the @a_new_decorator is just a short way of saying: a_function_requiring_decoration = a_new_decorator(a_function_requiring_decoration)

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

上面的代码等价于我们熟悉的:

def a_new_decorator(a_func): def wrapTheFunction(): print("I am doing some boring work before executing a_func()") a_func() print("I am doing some boring work after executing a_func()") return wrapTheFunction def a_function_requiring_decoration(): print("I am the function which needs some decoration to remove my foul smell") a_function_requiring_decoration() #outputs: "I am the function which needs some decoration to remove my foul smell" a_function_requiring_decoration = a_new_decorator(a_function_requiring_decoration) #now a_function_requiring_decoration is wrapped by wrapTheFunction() a_function_requiring_decoration() #outputs:I am doing some boring work before executing a_func() # I am the function which needs some decoration to remove my foul smell # I am doing some boring work after executing a_func()

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

不过一开始上面被装饰过的函数名字已经悄悄发生“改变”,如果print下可以看出(如下代码)。

解决方案

@wraps接受一个函数来进行装饰,并加入了复制函数名称、注释文档、参数列表等等的功能。这可以让我们在装饰器里面访问在装饰之前的函数的属性。

print(a_function_requiring_decoration.__name__) # Output: wrapTheFunction

1

2

最终加上@wraps的代码如下:

from functools import wraps def a_new_decorator(a_func): @wraps(a_func) def wrapTheFunction(): print("I am doing some boring work before executing a_func()") a_func() print("I am doing some boring work after executing a_func()") return wrapTheFunction @a_new_decorator def a_function_requiring_decoration(): """Hey yo! Decorate me!""" print("I am the function which needs some decoration to " "remove my foul smell") print(a_function_requiring_decoration.__name__) # Output: a_function_requiring_decoration

1

2

3

4

5

6

7

【python】装饰器!property和setter用法

8

9

10

11

12

13

14

15

16

17

18

5.property和setter用法

class Timer: def __init__(self, value = 0.0): self._time = value self._unit = 's' # 使用装饰器的时候,需要注意: # 1. 装饰器名,函数名需要一直 # 2. property需要先声明,再写setter,顺序不能倒过来 @property def time(self): return str(self._time) + ' ' + self._unit @time.setter def time(self, value): if(value < 0): raise ValueError('Time cannot be negetive.') self._time = value t = Timer() t.time = 1.0 print(t.time)

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

reference

https://www.runoob.com/w3cnote/python-func-decorators.html

Python

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:步步为营UML建模系列总结
下一篇:OAuth 2.0只是授权协议,OIDC才是认证授权协议
相关文章