python装饰器property和setter用法
作者:wx62cea850b9e28??????? 发布时间:2023-02-14 09:01:05
标签:python,装饰器,property,setter,用法
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'
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
(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: <function greet at 0x7f2143c01500>
#上面清晰地展示了`a`现在指向到hi()函数中的greet()函数
#现在试试这个
print(a())
#outputs: now you are in the greet() function
在 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!
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)
上面的代码等价于我们熟悉的:
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()
不过一开始上面被装饰过的函数名字已经悄悄发生“改变”,如果print下可以看出(如下代码)。
解决方案:
@wraps接受一个函数来进行装饰,并加入了复制函数名称、注释文档、参数列表等等的功能。这可以让我们在装饰器里面访问在装饰之前的函数的属性。
print(a_function_requiring_decoration.__name__)
# Output: wrapTheFunction
最终加上@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
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)
来源:https://blog.51cto.com/u_15717393/5470902


猜你喜欢
- 利用python,可以实现填充网页表单,从而自动登录WEB门户。(注意:以下内容只针对python3)环境准备:(1)安装python (2
- 处理数据时我们经常需要从数组中随机抽取元素,这时候我们可以考虑使用np.random.choice()函数语法格式numpy.random.
- 函数原型pd.read_csv(filepath_or_buffer, sep=',', delimiter=None, h
- 前言大家都知道,Sublime Text 安装插件一般从 Package Control 中直接安装即可,当我安装 node js 插件时候
- update :单表的更新不用说了,两者一样,主要说说多表的更新 O
- 注意:index.html再次声明变量的时候注意空格的问题来源:https://blog.csdn.net/guofeng93/articl
- python中的email模块可以方便的解析邮件,先上代码#-*- encoding: gb2312 -*-import osimport
- Python:type、object、classPython: 一切为对象>>> a = 1>>> ty
- My Sql 大部分都是用绿色版(解压版) 然后注册服务 简单方便。但是。配置文件头痛的一逼。首先配置mysql的环境变量。mySQL 环境
- login.html <script language = "javascript" type = "t
- 迷宫问题问题描述:迷宫可用方阵 [m, n] 表示,0 表示可通过,1 表示不能通过。若要求左上角 (0, 0) 进入,设计算法寻求一条能从
- 我就废话不多说了,大家还是直接看代码吧~#编写程序将列表中的偶数变成他的平方def word_len(s): # s = [i
- max() 方法返回其参数最大值:最接近正无穷大的值。语法以下是max()方法的语法:max( x, y, z, .... )参
- 序言:php错误就是会使脚本运行不正常的情况。php的错误有很多种,包括warning、notice、deprecated、fetal er
- 有时候,为了获取查询结果的部分数据,需要对变量进行一些处理,在网上查了一圈,只发现了这两个方法:返回查询结果的切片在返回给前端的结果中,通过
- 在深度学习的数据训练过程中,虽然tensorflow和pytorch都会自带打乱数据进行训练的方法,但是当我们自己生成数据,或者某些情况下依
- 本文实例讲述了js实现黑色简易的滑动门网页tab选项卡效果。分享给大家供大家参考。具体如下:这是一款js实现的黑色风格网页滑动门菜单,虽然简
- 开始我们将通过示例介绍偶数列表以及在 Python 中创建偶数列表的不同方法。什么是偶数本教程展示了如何在 Python 中制作偶数列表。
- 查询mysql表是否被损坏命令,如下:# CHECK TABLE 表名mysql的长期使用,肯定会出现一些问题,一般情况下mysql表无法访
- 前言Python 是每个程序员都喜欢的语言,因为它易于编码和易于阅读的语法。但是,你知道 python 有一些很酷的技巧可以用来让事情变得更