Python3进阶:高级特性一
Python3进阶:高级特性一
镇长接下来的文章学习Python的高级内容,这部分和之前相比有一定的难度,需要认真学习。加油吧,少年!
两个魔法变量
在Python中有两个变量参数容易困扰我们。它们是*args
和**kwargs
。接下来我们看看究竟是什么意思!
*args
*args
和**kwargs
主要用于函数定义。可以将不定数量的参数传递给函数。*args
是用来发送一个非键值对的可变数量的参数列表给函数。
举个🌰:
1 | def test_var_args(f_arg, *argv): |
输出结果:
1 | first normal arg: yasoob |
输出结果看出:
f_arg
只对应一项。
**kwargs
**kwargs
允许将不定长度的键值对,作为参数传递。
🌰:
1 | def greet_me(**kwargs): |
输出结果:
1 | name == yasoob |
*args
和**kwargs
使用
使用它们调用函数,🌰:
1 | def test_args_kwars(arg1, arg2, arg3): |
标准参数与
*args
、**kwargs
在使用时的顺序。
some_func(frags, *args, **kwargs)
调试(Debug)
调试在处理代码bug非常重要。
从命令行运行
1 | python3 -m pdb xxx.py |
触发调试功能,第一行指令处停止。
从脚本内部运行
设置断点,使用pdb.set_trace()
方法实现。
1 | import pdb |
命令列表
c
: 继续执行w
: 显示当前正在执行的代码行的上下文信息a
: 打印当前函数的参数列表s
: 执行当前代码行,并停在第一个能停的地方(相当于单步进入)n
: 继续执行到当前函数的下一行,或者当前行直接返回(单步跳过)
n
和s
区别:s
单步进入会进入当前行调用函数内部并停在里面,而单步跳过会全速执行完当前行调用的函数,并停在当前函数的下一行。
其他内容请参考官方文档
生成器
前面在学习类时,简单学习了生成器。接下我们将深入学习生成器相关知识。学习生成器之前,我们需要了解迭代器和相关内容。
迭代器是让程序可以迭代遍历一个容器的对象。分为三个部分:
- 可迭代对象(iterable)
- 迭代器(iterator)
- 迭代(iteration)
可迭代对象(iterable)
Python中任意对象,只要它定义了可以返回一个迭代器的__iter__
方法,或者定义了可以支持下索引的__getitem__
方法,那么他就是一个可迭代对象。简单来说,就是提供了迭代器的对象。
迭代器(iterator)
对象只要实现__next__
方法,它就是一个迭代器。
迭代(iteration)
例如,循环遍历就是迭代。
生成器
生成器也是一种迭代器,但是只能对其迭代一次。因为它们并没有把所有的值存在内存中,而是运行时生成值。通过遍历来使用它。另外,它们并不返回值,而是yield
一个值。
举个🌰
1 | def generator_function(): |
上面的只是例子。真正的运行场景是:不想在同一时间创建大量结果集分配到内存中,减少资源消耗。在Python3中生成器应用很广广泛。
高级函数
Map, Fiter和Reduce三个函数为函数式编程提供便利。
Map
Map
将一个函数映射到一个输入列表的所有元素上。
格式:
1 | map(函数, 列表) |
将列表中元素一个个传递给函数,并收集输出。在Python3中返回的是迭代器。
通常,使用匿名函数来配合map
。
例如:
1 | squared = list(map(lambda x: x ** 2, range(1, 10))) |
Filter
顾名思义,Filter过滤列表中的元素,并且返回一个所有符合要求的元素组成的列表。符合要求就是函数映射到该元素时返回值为True。
1 | number_list = range(-5, 5) |
Reduce
对一个列表进行一些计算并返回结果时, Reduce是非常有用的函数。
例如:计算乘积
1 | from functools import reduce |
装饰器
装饰器(Decorators)是Python的一个重要部分。他们是修改其他函数的功能的函数。
学习装饰器之前,你应该知道一切皆对象
、函数定义函数
、函数返回函数
、将函数作为参数传递
。如果对上面内容不了解,那请补一下面向对象吧。
第一个装饰器
1 | def a_new_decorator(a_func): |
装饰器作用:封装了一个函数,用来修改函数行为
上面的简短写法:
1 | @a_new_decorator |
上面的
@a_new_decorator
就相当于a_function_requiring_decoration = a_new_decorator(a_function_requiring_decoration)
。
👆是装饰器的基本工作原理。但是这样写存在一个问题。
请看:
1 | print(a_function_requiring_decoration.__name__) |
我们希望的结果是,Output应该输出:
a_function_requiring_decoration
。Python提供了一个函数解决这个问题,就是functools.wraps
。
修改方法:
1 | def a_new_decorator(a_func): |
在
wrapTheFunction
之前添加@wraps()
。注意需要引包from functools import wraps
。
好了现在学会装饰器了,接下来练习一下吧!
1 | from functools import wraps |
@wraps接受一个函数来进行装饰,并加入了复制函数名称、注释文档、参数列表等等的功能。这可以让我们在装饰器里面访问在装饰之前的函数的属性
使用场景
授权检验
装饰能有助于检查某个人是否被授权使用一个web应用的断点。它们被大量使用在Flask和Django框架中。
日志
日志是装饰器运行的另一个亮点。
带参数的装饰
@wraps
可以接收一个参数,就像普通的函数一样。我们也可以实现。
例子:
1 | from functools import wraps |
装饰器类
上面只是将装饰器写成函数的形式,接下来,以类的形式实现装饰器。
下面还是以logit为例:
1 | from functools import wraps |
调用方法和函数形式相同。
因为是装饰器类,所以具有类的特性:
1 | class email_logit(logit): |
@email_logit
和@logit
产生同样的效果,只是前者会发送email。
小结
以上内容学习了*args
和**kwargs
作用和区别,高阶函数,Debug调试,生成器和装饰器的原理和应用。学会不是目的,应用才是王道。