Python函数与装饰器入门一
Posted buono
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Python函数与装饰器入门一相关的知识,希望对你有一定的参考价值。
语句简写
三元运算(三目运算)
解决if,else条件的简写。
v = A if 条件 else B
# 如果条件为真,就把A赋值给V,否则赋值B
lambda表达式
简单函数的简写
def func(a1,a2):
return a1+a2 #这种简单返回数值的函数形式,可以简化为:
func = lambda a1,a2:a1+a2 #这种简便写法叫做lambda表达式,和上面的形式没有区别
两者可以相互结合,实现简写
func = lambda a1,a2: a1 if a1>0 else a2 #函数根据不同的条件输出不同的值
函数
定义
之前简单的代码实现都是面向过程编程,实现一次就需要写一次,可读性非常差。
通过函数可以实现面向对象编程。 简单来说把一段代码取名,以后直接用名字来调用这一段代码,并且可以动态更改这段代码里面的参数。提高可读性
基本结构
#定义函数
def 函数名(设定的形式参数):
#函数内容
#执行函数
函数名(输入变量的实际参数)
函数的返回值
执行完函数后,可以指定返回一些参数
def haoran(a):
a += 1
return a #返回值,不写返回None,返回数字、元组、字典等都可以
val_a = haoran(22) #执行函数后把return值赋给val_a
函数执行过程中,一旦遇到return,就不再继续执行了
文件操作的补充
打开文件,关闭文件的操作容易忘记,可以直接写
with open("/tmp/foo.txt") as file:
data = file.read()
#这样就不用f.close操作了
函数参数(arguments)
1.位置参数: 按照顺序来传参数,那少传,多传都会报错。
def func(a1,a2):
print(a1,a2)
func(22,99)
2.关键字传参数:
def func(a1,a2):
print(a1,a2)
func(a1=22,a2=99)
以上两者可以混合使用,位置前,关键字参数在后
3.默认参数
def func(a1,a2=9): #a2不传就等于9, 传就按输入的来
print(a1,a2)
func(a1=22,a2=99)
4.万能参数
def func(*a1): #带*, 默认会写成*args(arguments的缩写)
print(a1)
func(1,232,534534) #把所有参数传给a1,成为一个元组
func(*(1,2,3,4)) #加*就打散所有元素加进去,否则只分开最外层
带*的参数只能用位置传参
带**的情况
def func(**kwargs):#**情况一般写kwargs
print(kwargs)
func(k1 = 1, k2 = 'ran')
#输出:{'k1': 1, 'k2': 'ran'} ,为字典
作用域
整个代码环境从上到下执行的地方,叫做全局作用域。
函数没有执行的时候那几行代码实际是跳过的,这就叫局部作用域。 只有在你调用这个函数的时候,这几行代码才开始从上到下执行。 作用域中的数据归自己所有,别人访问不到。 只有最后会返回一个值到全局中去。
作用域中引用数据规则:优先在自己的作用域找,自己的找不到就去父级, 直到全局作用域,全局都没有就报错。
作用到全局的方法
global 可以作用到全局
name = 'ran'
def func():
global name #这下就把“hao” 给赋到全局变量里面了,不然只有在函数作用域里name = hao
name = "hao"
func()
nonlocal 函数以此类推,只赋到上一级变量
书写规范
以后写全局变量名字必须大写,局部变量可大可小写
函数高级
函数的赋值
函数也可以和变量一样进行赋值
def func():
print(1)
v1 = func
v1() #这样也可以用函数
以此内推,函数名也可以进行调用,例如嵌入到列表里
def func():
print(1)
V_list = [func,func2] #这个列表里有两个函数, 可以根据需要进行调用,调用后加括号即可执行
同样,函数可以当作字典的value,但是一般不当key
闭包
为函数创建一块区域为其维护自己数据,以后执行时方便调用
def outer(x):
def inner(y):
return x + y
return inner
inner(y)就是这个内部函数,对在外部作用域(但不是在全局作用域)的变量进行引用:x就是被引用的变量,x在外部作用域outer里面,但不在全局作用域里,则这个内部函数inner就是一个闭包
装饰器
装饰器的作用是在原函数的基础上添加功能,但是不破坏原函数的结构。 做法是包上一层。
def wrapper(func):
def inner():
# 想在原函数基础上增加打印“登录” 这个功能
print("登录")
func() #原函数f1被当作参数传到func中了,所以此处就是运行原函数
return func() #装饰器结束,返回和原函数一样的值
return inner
@wrapper # f1 = wrapper(f1)的简写(也叫语法糖) , 这样func=f1函数,f1又重新定义为inner函数了
#@www(9) 这种情况,先计算函数的返回值,随后必须得到的是一个函数名,然后再同理上面一步
def f1():
# 这是基本的函数,实现打印123
print(1)
f1()
这样可以保证调用接口还是f1(),新增了功能。 返回值不变
如此看最外层wrapper好像多此一举,好像只需内层函数就满足了新增功能的需求。 其实外层函数的作用是让这个嵌套不执行,保持和原来一样的启动方式。
万能参数
如果不加入万能参数,装饰器就不能同时应对存在不同数量参数这种情况。
def wrapper(func):
def inner(*args,**kwargs): #这样完美解决,想传啥就传啥~
print("登录")
func(*args,**kwargs)
return func()
return inner
装饰器的推导
列表推导式
val = [i for i in "ran"] #循环ran的字符,每循环一个,就加入到val这个列表中
val = [100 for i in "ran"] #每循环一次,就添加“100”到列表中
val = [func for i in "ran"] #每循环一次,还可以添加函数到列表里,但是不会执行
注意:
在列表里面生成了10个函数,但是这些函数并没有执行,所以不会给i赋值。 因此列表中的10个函数的i都是一样的。 我们从列表中取任意函数来运行,返回值i都只能读取到 for循环结束的时候i的值9
def func:
return i
v8 = [func for i in range(10)]
print(v8[0]()) #无论取哪个函数,i的值都是循环结束时的9,之前循环0-8时,函数没有执行,所以也没存储0-8
字典,集合的推导式以此类推
time 模块
import time
v = time.time() #获取当前时间,从0时区的1970年开始以秒为单位
time.sleep(5) #运行至此行停顿5秒
递归
函数自己调用自己,尽量不要用递归,因为效率低,内存一直在用。 最好用while循环代替。
用递归来计算斐波那契数列
斐波那契数列: 从第三项开始,每一项都等于前2项之和。 1、1、2、3、5、
def func(a, b):
print(b)
func(b, a + b)
func(0, 1)
带参数的装饰器
相当于把装饰器再包裹一层,这样可以获得一个可以随时调用的变量、
def x(counter):
def wrapper(func):
def inner(*args,**kwargs):
print("登录")
func(*args,**kwargs)
return func()
return inner
return wrapper
@x(9)#可以传参数
def f1():
pass
以上是关于Python函数与装饰器入门一的主要内容,如果未能解决你的问题,请参考以下文章