目录
- 闭包
- 装饰器
- 相关类型参数
闭包
定义:如果在一个内部函数里,对在外部作用域(但不是在全局作用域)的变量进行引用,那么内部函数就被认为是闭包。
def curve_pre(x): # 定义一个函数,其返回值是一个函数curve
# 故当定义时相当于调用函数curve(闭包的特征)
a = 25 # 在外部作用于(父作用域)里定义变量
def curve(x): # 在引用curve_pre函数时就定义了a变量
return a * x * x
return curve
a = 10 # 函数体(父函数)外部变量,无法进入函数里
f = curve_pre() # 调用父函数
print(f(2)) # 输入实参,输入子函数里
可以看出,闭包是由一个函数与外部环境定义的变量构成,此闭包在调用时不会受到外部变量的影响,闭包的意义是保存一个环境。
用闭包实现累加算法:
nonlocal 用法:
origin = 0
def factory(pos):
def go(step):
nonlocal pos # 定义这个pos不只是go函数里的pos,即第一次计算时可引用父函数里的pos
new_pos = pos + step
pos = new_pos # 通过pos储存先前的计算值
return new_pos
return go # 返回go函数(闭包)
tourist = factory(origin) # 调用factory函数并赋值pos
print(tourist(2)) # 把值传入step
print(tourist(3))
print(tourist(5))
# 输出2, 5, 10装饰器
- 对于需要新增功能时,可以不改变原先函数内部的内容和调用的形式,在外面定义新增功能的装饰器,在用@引用装饰器。
- 装饰器可用于多个不同的函数,即定义一个新增功能,可以用于多种不同但需要此功能的函数里。
# 任务:新增打印时间的功能
import time()
def decorator(func): # 定义一个函数,其作用为增加新功能
# 通过func形参把原先函数引入
def wrapper():
print(time.time()) # 输出新增的功能
func() # 输出原函数的功能
return wrapper # 返回子函数(闭包)
@decorator # 在原函数的定义前使用装饰器,即可新增原函数功能
def f1():
print('This is a function')
f1()
# 输出:1578235993.4626515
This is a function 多参数函数的装饰器:使用包裹位置参数和包裹关键字参数
import time
def decorator(func):
def wrapper(*args, **kw): # *args为包裹位置参数
# **kw为包裹关键字参数,接收所有关键字参数
print(time.time())
func(*args, **kw)
return wrapper
@decorator
def f1(func_name):
print('This is a function named' + func_name)
@decorator
def f2(func_name1, func_name2):
print('This is two function named' + func_name1 + ',' + func_name2)
@decorator
def f3(func_name1, func_name2, **kw):
print('This is two function named' + func_name1 + ',' + func_name2)
pint(kw)
f1('卖小写')
f2('石敢当', '卖小邪')
f3('石敢当', '卖小邪', a = 1, b = 2, c = '123')
Python相关参数类型
2. 关键字参数:用于函数调用,通过“键--值”形式加以指定。可以让函数更加清晰,容易使用,同时也清除了参数的顺序需求。
def print_hello(name, sex):
print('hello' + name + sex)
print_hello(sex = '男', name = '石敢当') # 用关键字参数可以改变传入的位置
3. 默认参数:用于定义函数,为参数提供默认值,调用函数时可传可不传该默认参数的值。
例:def(name = '石敢当', age, sex)
4. 可变参数:定义函数时,有时我们不确定调用的时候会传递多少个参数,此时可以用包裹参数,来进行参数传递。
- 包裹位置传递: *args
我们传进去的所有参数都会被args变量收集,他会根据传进参数的位置合并为一个元组,args是元组类型。
- 包裹关键字传递: **kw
kw是一个字典,收集所有关键字参数
5. 解包裹参数: *和**也可以在函数调用的时候使用,称之为解包裹。
- 在传递元组时,让元组的每一个元素对应一个位置参数
def print_hello(name, sex):
print name, sex
args = ('石敢当', '男')
print_hello(*args)- 在传递字典时,让字典的每个键值作为一个关键字参数传递给函数
def print_hello(kw):
print kw
kw = {'name' = '石敢当', 'sex' = '男'}
print_hello(**kw)最后,感谢观众老爷的浏览,下面是卖小邪的微信号,希望有志同道合的码友能够加下,也更希望有业界大佬来指导小憨憨的编程之路!!!
感谢感谢
