欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

【Py3】模块和语法总结

程序员文章站 2022-03-28 17:49:55
python3语法和模块,包块迭代器,生成器和装饰器等...

collections模块

Python内置标准库中的collections提供了一些很实用的数据结构

  • namedtuple:用于创建元祖子类的工厂函数(factory function),可以通过属性名访问元索引
  • deque:双端队列
  • ChainMap:类似字典类,用于创建多个映射的单一视图
  • Counter:字典子类,对可哈希对象进行计数
  • OrderedDict:字典子类,可以保存元素的添加顺序
  • defaultdict:字典子类,可以通过调用用户自定义的工厂函数来设置缺失值

迭代器

迭代器是实现了迭代协议的容器对象,基于以下两种方法

  • __next__:返回容器的下一个元素
  • __iter__:返回迭代器本身

当迭代完所有序列时,会发生StopIteration异常,可以通过捕获该异常停止迭代. 实现自定义迭代器,可以编写一个具有__next__方法的类,只要该类提供返回迭代器实例的__iter__的特殊方法

class MyIter:
    def __init__(self, step):
        self.step=step
    def __next__(self):
        if self.step<=0: raise StopIteration
        self.step-=1
        return self.step
    def __iter__(self):
        return self
    
def main():
    for element in MyIter(5): print(element, end=' ')
    
if __name__ == "__main__":
    main()

生成器

基于yield语句,生成器可以暂停函数并返回一个中间结果,该函数可以保存执行上下文(context),支持恢复现场.
使用yield语句生成Fibonacci数列

def fibonacci():
    a, b=0, 1
    while True:
        yield b
        a, b = b, b+a
    
def main():
    fib=fibonacci()
    for i in range(10): print(next(fib), end=' ')
    
if __name__ == "__main__":
    main()

在数据序列转换算法中,生成器可以降低算法的时间复杂度,将每个序列看做一个iterator,然后将其合并为一个高阶函数,形成处理链.

def power(values):
    for value in values:
        print('powering :{}'.format(value))
        yield value

def adder(values):
    for value in values:
        print('adding :{}'.format(value))
        if value & 0x01: yield value+1
        else: yield value

def main():
    e=[i for i in range(1, 20, 3)]
    ans=adder(power(e))
    for _ in range(3): next(ans)
    
if __name__ == "__main__":
    main()

生成器可以通过next函数与调用的代码进行交互,值可以通过send方法传递. 这种特性是Python中协程和异步并发的基础.

def robot():
    print('tell me your problem')
    while True:
        ans=(yield) # yield作为表达式使用
        if ans:
            if ans.endswith('?'): print("ROBOT: what's your problem?")
            elif 'good' in ans: print('ROBOT: that is good')
            elif 'bad' in ans: print('ROBOT: No more bad, bro')
                                        
def main():
    rob=robot()
    next(rob)
    rob.send('I feel bad?')
    rob.send('I feel good')
    rob.send('I amd bad')
                                        
if __name__ =='__main__':
    main()

装饰器

装饰器的作用是函数包装,实现函数的功能加强,避免函数的重复定义.

class Decorators:
    @staticmethod
    def foo1(): print('static method')
    @classmethod
    def foo2(): print('class method')

装饰器通常是一个命名对象,在被装饰函数调用时接受单一参数,并返回一个可调用对象,任何实现了__call__方法的对象均为可调用的.

通用模式

作为函数

函数返回包装原始函数调用的一个子函数

def mydecorator(func):
	def wrapped(*args, **kwargs):
		# do something
		ans=func(*args, **kwargs)
		# do something
		return ans
	return wrapped

作为类

当装饰器需要复杂的参数化或者依赖特定的状态,使用自定义类比较好

class DecoratorClass:
	def __init__(self, func):
		self.func=func
	def __call__(self, *args, **kwargs):
		# do something
		ans=self.func(*args, **kwargs)
		# do something
		return ans

参数化装饰器

需要两层包装,指定重复调用次数,每次被调用时会重复执行一个装饰器函数.

def rep(n=3):
    '''
    多次重复执行装饰函数,返回最后一次原始函数调用值作为结果
    '''
    def mydecorator(func):
        def wrapper(*args, **kwargs):
            ans=None
            for _ in range(n):
                ans=func(*args, **kwargs)
            return ans
        return wrapper
    return mydecorator

@rep(5)
def foo(): print("this is foo")
@rep()
def bar(): print("this is bar")
    
foo()
bar()

保存内省的装饰器

装饰器组合创建了新函数,并返回一个新对象,但是没有考虑到原始函数的meta-data,解决该问题的方法就是使用functools模块内置的wraps()装饰器.

from functools import wraps
def preserve_dec(func):
    @wraps(func)
    def wrapped(*args, **kwargs): return func(*args, **kwargs)
    return wrapped

@preserve_dec
def foo():
    """this is doc string"""

print(foo.__name__)
print(foo.__doc__)
    

本文地址:https://blog.csdn.net/qq_18822147/article/details/107661060

相关标签: Python