Python 迭代器,生成器,装饰器,可变参数总结

函数中的可变参数列表

当函数调用可变个数的参数时,这些可变参数被包装进一个元组,在可变参数前,可以有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
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值