函数中的可变参数列表
当函数调用可变个数的参数时,这些可变参数被包装进一个元组,在可变参数前,可以有0到多个普通的参数,多个参数用*作为前缀.
def concat(*args, sep="/"):
return sep.join(args)
concat("earth", "mars", "venus")
'earth/mars/venus'
concat("earth", "mars", "venus", sep=".")
'earth.mars.venus'
相反的情况
要传递的参数已经是一个列表,但是调用的函数却接手分开一个个的参数值,这时候就要把已有的列表拆开,,可以在调用函数时加一个*操作符来自动把参数列表拆开
list(range(3, 6))
[3, 4, 5]
args = [3,6]
list(range(*args)) # 和第一行的效果相同
[3,4,5]
迭代器
大部分容器对象都可以用for循环
for element in [1, 2, 3]:
print(element)
for element in (1, 2, 3):
print(element)
for key in {'one':1, 'two':2}:
print(key)
for char in "123":
print(char)
for line in open("myfile.txt"):
print(line, end='')
在后台, for语句在容器对象中调用 iter() 。该函数返回一个定义了 next()方法的迭代器对象,它在容器中逐一访问元素。没有后续的元素时, next() 抛出一个 StopIteration 异常通知 for语句循环结束。你可以是用内建的 next()函数调用 next() 方法;以下是其工作原理的示例:
s = 'abc'
it = iter(s)
it
<iterator object at 0x00A1DB50>
next(it)
'a'
next(it)
'b'
next(it)
'c'
next(it)
Traceback (most recent call last):
File "<stdin>", line 1, in ?
next(it)
StopIteration
了解了迭代器协议的后台机制,就可以给自己的类添加迭代器行为,定义一个iter()方法,使其返回一个带有next()方法的对象,如果这个类已经定义了next(),那么iter()只需要返回self.
class Reverse:
"""Iterator for looping over a sequence backwards."""
def __init__(self, data):
self.data = data
self.index = len(data)
def __iter__(self):
return self
# __next__()自定义迭代方法.
def __next__(self):
if self.index == 0:
raise StopIteration
self.index = self.index - 1
return self.data[self.index]
生成器
在Python中,这种一边循环一边计算的机制,称为生成器:generator。
创建一个generator,有很多种方法。第一种方法很简单,只要把一个列表生成式的[]改成(),就创建了一个generator.
第二种:如果一个函数定义中包含yield关键字,那么这个函数就不再是一个普通函数,而是一个generator.
在执行过程中,遇到yield就中断,下次又继续执行。
生成器Generator是创建迭代器简单而强大的工具,需要返回数据的时候使用yield语句,每次next()被调用时,生成器回复它脱离的位置.
def reverse(data):
for index in range(len(data)-1, -1, -1):
yield data[index]
for char in reverse('golf'):
print(char)
f
l
o
g
装饰器
装饰器本质上是一个Python函数,它可以让其他函数在不需要做任何代码变动的前提下增加额外功能,装饰器的返回值也是一个函数对象
def now():
print("2018")
>>> f = now
>>>f()
2018
假设我们要增强now()函数的功能,比如,在函数调用前后自动打印日志,但又不希望修改now()函数的定义,这种在代码运行期间动态增加功能的方式,称之为“装饰器”(Decorator)。
本质上,decorator就是一个返回函数的高阶函数。所以,我们要定义一个能打印日志的decorator,可以定义如下.
def use_logging(func):
def wrapper(*args,**kw):
print("call%s():"%func._name_)
func(*args,**kw)
print("after")
return
return wrapper
def bar():
print('i am bar')
bar = user_loggin(bar)
bar()
函数use_logging就是装饰器,wrapper是组装的最终函数
简单装饰器
def use_logging(func):
def wrapper(*args, **kw):
print('call %s():' % func.__name__)
func(*args, **kw)
print("after")
return
return wrapper
#@符号是装饰器的语法糖,在定义函数的时候使用
#避免再一次赋值操作
@use_logging
def foo():
print('i am foo')
@use_logging
def bar():
print('i am bar')
带参数的装饰器
装饰器语法允许在调用时,提供其他参数,可以在装饰器的外面再封装一层
def complex_fengzhuang(参数):
def user_logging(func):
def wrapper(*args,**kw):
print("call %s:"%func._name_)
#deal 参数
func(*args,**kw)
print("after")
return
return wrapper
return user_logging