三神器-迭代器、生成器和装饰器

1.迭代器与生成器

1.1 迭代器

  • 基础的迭代器初始和访问
i = iter('abc')
print(i.__next__())
print(i.__next__())
print(i.__next__())
for i in iter('abc'):
    print(i)
  • 针对类的时候,需要__iter__(self)__next__(self)结合。并且,使用raise stopIteration来停止迭代器。
class MyIterator(object):
    def __init__(self):
        self.a = 0
        self.b = 1
    def __iter__(self):
        return self
    def __next__(self):
        self.a,self.b = self.b,self.a+self.b
        if self.a>100000:
            raise StopIteration # 这样就会自动停止
        return self.a
for n in MyIterator():
    print(n)

1.2 生成器

  • 生成器:yield。访问:obj.__next__()

2. 闭包

  1. 注意闭包的用法:返回内部函数
  2. func是函数引用,func()是函数调用
def greeting_conf(prefix):
    def greeting(name):
        print (prefix, name)
    return greeting
mGreeting = greeting_conf("Good Morning") # 现在的mGreeting是function:greeting
print ("function name is:", mGreeting.__name__) 
print ("id of mGreeting is:", id(mGreeting))
print()
aGreeting = mGreeting("Good Afternoon") 
print ("inner function returns:",aGreeting)
print ("id of aGreeting is:", id(aGreeting))

3. 装饰器

3.1 类方法:@classmethod AND @staticmethod

  • 避免实例化,可以直接调用类的方法。
class MyClass:
    bar = 1
    def foo(self):
        print('MyClass')
    @classmethod #避免硬编码
    def classFoo(cls):
        print('classFoo',end=" ")
        print(cls.bar)
        cls().foo()
        # cls.foo() # 这种调用会报错。没有self
    @staticmethod
    def staticFoo():
        print('staticFoo',end=" ")
        print(MyClass.bar)
        MyClass().foo()
        # MyClass.foo() # 这种调用会报错。没有self
# 不用实例化,直接调用
MyClass.classFoo()
MyClass.staticFoo()

3.2 @property类装饰器

  • @property相当于get,对应的之后的装饰器,都需要 func+setter/deleter
class MyClass:
    def __init__(self):
        self.__x = None
    @property
    def x(self):
        return self.__x
    @x.setter
    def x(self,value):
        self.__x = value
    @x.deleter
    def x(self):
        del self.__x

myclass = MyClass()
print(myclass.x) # 调用@property
myclass.x = 100 # 调用@x.deleter
print(myclass.x)
del(myclass.x) # 调用@x.deleter
try:
    print(myclass.x)
except Exception as error:
    print('Fail',error)

3.3 自定义装饰器

虽然有很多对装饰器的理解,但是,楼主还是觉得,装饰器是对函数行为的定义。(#^.^#)

  • 最简单的装饰器,闭包+函数参数
def log(func):
    # 最基础的装饰器
    def wrapper(*args,**kw):
        print("call %s();" % func.__name__)
        # return func(*args,**kw) # 可以不注释掉,就会调用
    return wrapper
@log
def now():
    print("Now")
now()
  • 带参数的装饰器:3层封装,注意声明的时候必须有括号!!!
def log(text="我是默认文本"):
    # 带参数的装饰器
    def decorator(func):
        def wrapper(*args,**kw):
            print(func.__name__)
            return func(*args,**kw)
        return wrapper
    return decorator
@log() #注意:有参数的装饰器声明的时候,必须有括号
def now():
    print("Now")
now()
  • 下面这个算是很有用的装饰器用法,定义了函数行为。
def Before(request, kargs):
    print('before')
def After(request, kargs):
    print('after')
def Filter(before_func, after_func):
    def outer(main_func):
        def wrapper(request, kargs):
            before_result = before_func(request, kargs)
            if (before_result != None):
                return before_result
            main_result = main_func(request, kargs)
            if (main_result != None):
                return main_result
            after_result = after_func(request, kargs)
            if (after_result != None):
                return after_result
        return wrapper
    return outer
@Filter(Before, After)
def Index(request, kargs):
    print('index')
Index(1,2)

输出结果:

before
index
after

欢迎进一步交流本博文相关内容:
GitHub地址 :https://github.com/AsuraDong/Blog
CSDN地址 : http://blog.csdn.net/asuradong
简书地址:http://www.jianshu.com/u/d1570f4a618a
博客园地址 : http://www.cnblogs.com/AsuraDong/(不一定及时更新)
也可以致信进行交流 : [email protected]
欢迎关注个人微博:http://weibo.com/AsuraDong
欢迎转载 , 但请指明出处  :  )


你可能感兴趣的:(三神器-迭代器、生成器和装饰器)