闭包:
什么是闭包,一句话,在函数中再嵌套一个函数,并且引用外部函数的变量,这就是一个闭包了
一般外部函数的返回值为内部函数
def outer(x):
def inner(y):
return x + y
return outer # 外部函数的返回值,是内部函数
print(outer(6)(5))
python 循环中不包含域的概念
range() 函数饭返回一个可迭代对象(类型是对象)
xrange() 与range类似,只是返回一个“xragne object” 对象,而非数组list
要生成很大的数字序列的时候,用xrange回避range性能优很多,因为不需要一上来就开辟一块很大的空间。
装饰器:
装饰器就是一个闭包,装饰器是闭包的一种应用,python装饰器就是用于拓展原来函数功能一种函数,这个函数的特殊之处在于它的返回值也是一个函数,使用python装饰器的好处就是在不用更改原函数的代码前提下给函数增加新的功能,使用时在需要的函数前加上@xx
#定义了一个函数
def foo():
#函数功能
print("------1-------")
#定义了另一个函数传入了一个形参
def bar(func): # 这里啊 func == foo 是 Ture
#这段代码在干什么
func() # func() == foo() #打印func() 其实就是 foo()
#python的函数可以像普通变量一样作为参数传递给函数,将函数foo 作为bar函数的实参
bar(foo) # 这边接受的是foo函数,要使用函数不应该是 foo() 如果你知道多线程 中有一个分配线程
# def test1()
# print('-----1------')
# threading.Thread(target = test1) # 主线程会分配一个子线程给去执行test1 函数 ,主线程会在这里等待 子线程执行完毕后死掉
装饰器的本质是一个python函数或类,它可以让其他函数或者类在不需要做任何代码的前提下增加额外的功能,装饰器的返回值也是一个函数/类对象
def use_logging():
def wrapper():
pass
return wrapper # 返回的只是局部函数的对象并不会执行内部函数的中代码
def foo():
print('i am foo')
# 执行use_logging() 返回局部函数对象
use_logging()
<function __main__.use_logging.<locals>.wrapper()> # 函数对象
def use_logging(func): # func 形参
def wrapper():
print("--------1----------")
# # logging.warn("%s is running" % func.__name__)
# return func() # 把 foo 当做参数传递进来时,执行func()就相当于执行foo()
return wrapper # 返回的只是局部函数的对象并不会执行内部函数的中代码
def foo():
print('i am foo')
#use_logging() [执行效果] == 返回 wrapper
foo = use_logging(foo) # foo 实参 foo 是函数foo 用变量foo接受 # use_logging(foo) == wrapper
foo() foo() != 函数foo() 根据51行 所以得出 foo() == wrapper() # 它就会返回执行结果 --------1----------
def use_logging(func):
def wrapper():
print("--------1----------")
# # logging.warn("%s is running" % func.__name__)
return func() # 把 foo函数 当做参数传递进来时,执行func()就相当于执行foo()
# 因此返回了func() 就会去执行 函数foo 中的print('i am foo') 所以打印结果 i am foo
return wrapper # 返回的只是局部函数的对象并不会执行内部函数的中代码
def foo():
print('i am foo')
foo = use_logging(foo) # use_logging(foo) == wrapper
foo()
语法糖:
@ 就是语法糖的标识符 语法糖必须加在你想被作用的函数前面
例如:
@use_logging
def foo():
print("i am foo")
在下面的代码中
def use_logging(func):
def wrapper():
logging.warn("%s is running" % func.__name__)
return func()
return wrapper
语法糖的作用返回了 wrapper
@use_logging
# 给函数foo 添加了语法糖use_logging
def foo():
print("i am foo")
foo() #执行foo 函数其实也执行了语法糖use_logging
#foo() - 先去执行use_logging(foo)
。。。。。。
#暂时理解滞缓
语法糖提高程序的重复利用性 并增加了程序的可读性
*args、**kwargs
args 和 kwargs 通常还会在前面加上一两个星号,其实这是python开发人约定的变量名
其中args 是 arguments 的缩写,表示位置参数,kwargs 是keyword arguments 的缩写, 表示关键字参数这其实python中可变参数的两种形式,而且*args必须放在**kwargs的前面,因为位置参数在关键字参数的前面。
# 使用这段函数必须清楚元组可以进行遍历
def test_args(first,*args):
print('-----1-----',first)
print(type(args))
print(args)
for v in args:
# 这里的[1,2,3,4] 作为元组的一个元素,这里的元组样式是 ([1,2,3,4],)
print('-----2----',v)文章来源:https://www.toymoban.com/news/detail-460445.html
test_args(1,[2,3,4],4)
#得出原因了吧
for i in ([1,2,3,4],):
print(i)
#经过测试 args 接受一个不定参数的元组
**kwargs 允许你讲一个补丁长度的键值对,作为参数传递给一个函数
def greet_me(**kwargs):
for key, value in kwargs.items():
print('key = {0},value = {1}'.format(key, value))
greet_me(小明=18, 小李=20)
打印结果:
# 使用*args和**kwargs来调用函数
def test_args_kwargs(arg1, sex, age):
print ("年龄:",arg1)
print("性别:", sex)
print ("年龄:",age)
args = ('小李','男',18)
# 下面两端注释的原因是 .items() 迭代方法 不可行 元组不能迭代 list 也不能迭代
# for k ,y,e in list(args).items():
# print(k,y,e)
test_args_kwargs(*args)
文章来源地址https://www.toymoban.com/news/detail-460445.html
到了这里,关于Python 知识体系补全(闭包、装饰器、关键字参数**kwargs,位置参数*args)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!