深入理解 Python中的yield

深入理解 Python3 yield yield是 python 内置的关键字,它能产生一个生成器(Generator)。 0x01. Generators 只要函数中有yield就会变成一个generator object生成器对象,生成器对象可以迭代,但与iterable不同的是它只能迭代一次。先来看一个简单的例子 >>> def foo(): ... yield 1 ... yield 2 ... yield 3 ... >>> g = foo() >>> g <generator object foo at 0x7ffb08326ca8> >>> for i in g: ... print(i) ... ... 1 2 3 >>> for i in g: ... print(i) ... ... >>> 当你调用foo这个函数的时候,函数内部的代码并不立马执行 ,这个函数只返回一个生成器对象,如果有庞大的数据它不像iterable占用内存,会每次调用时才计算产生值。 其实for循环隐式的调用__next__()方法,直到遇到StopIteration停止。 >>> def bar(): ... yield 'a' # 第一次调用next()代码运行到这,产生'a' ... yield 'b' # 第二次调用next()代码运行到这,产生'b' ....

April 28, 2017 · 4 min · 748 words · Fython

Python装饰器(decorators)

Python装饰器(decorators) 装饰器(decorators)是Python强大的功能之一,语法上就支持(@符号)使用起来更方便,不需要用OOP的设计模式实现。装饰器其实就是个返回函数的函数(类),但可以有很多的玩法,下面将一一介绍。 函数(Functions) 讲装饰器之前,先回顾下一些函数的基础知识,装饰器就是这些简单功能的组合 函数接收函数作为参数 python中定义一个函数很简单如下 >>> def foo(): ... pass ... >>> foo <function foo at 0x1054157a0> >>> bar = foo >>> bar <function foo at 0x1054157a0> 定义了foo函数,而bar是对foo的引用,这很简单 因为python中一切皆对象,函数也是对象,一个函数也可以使用函数作为参数传入,和传其他对象一样(字符串、数字、列表 …) >>> def foo(): ... print("hello world") ... ... >>> def bar(f): ... print(f"call {f.__name__}") ... f() ... ... >>> bar(foo) call foo hello world bar函数就接收foo函数作为参数,内部执行foo函数。 函数内部定义函数 也可以在函数内部定义一个新的函数 >>> def foo(): ... def bar(): ... print("inner func") ... bar() ... ....

April 10, 2017 · 5 min · 902 words · Fython

Python中的类变量(class variables)和实例变量(instance variables)

Python中的类变量(class variables)和实例变量(instance variables) 类变量(Class Variables) 类变量是所有实例共享的变量,类和实例都能访问。也就是说类创建了之后类变量就已经初始化了之后所有的实例都共享这个变量不会单独创建。类变量需要定义在类的里面方法的外面 class Foo: cls_var = "this is class method" def __init__(self): pass f0 = Foo() f1 = Foo() print(f0.cls_var, id(f0.cls_var)) print(f1.cls_var, id(f1.cls_var)) print(Foo.cls_var, id(Foo.cls_var)) Foo.cls_var = "changed" print(f0.cls_var, id(f0.cls_var)) print(f1.cls_var, id(f1.cls_var)) print(Foo.cls_var, id(Foo.cls_var)) 输出 this is class method 4328472272 this is class method 4328472272 this is class method 4328472272 changed 4328412136 changed 4328412136 changed 4328412136 类Foo定义了cls_var类变量没有绑定到任何实例,类Foo和实例f0,f1它们引用的变量cls_var都是同一个地址,所以共享一个类变量,只要改变了所有引用的都会影响。以下是统计一共创建了多少实例的例子 class Person: count = 0 # class variable def __init__(self, name): self....

March 25, 2017 · 1 min · 191 words · Fython

Python类方法与静态方法的区别 | different between staticmethod and classmethod

Python中的装饰器@staticmethod和@classmethod的区别 staticmethod 当不想访问类变量和实例变量,又想优雅地写代码,方法不写在类外面避免以后代码难以维护。可以这样写封装在类里面 class TestStaticMethod(object): a = 0 def __init__(self): TestStaticMethod.a += 1 @staticmethod def smethod(): print('static method') bar = TestStaticMethod() bar.smethod() TestStaticMethod.smethod() 输出 static method static method [Finished in 0.0s] 静态方法@staticmethod即不能访问类变量也不能访问实例变量,被装饰的方法不需要传入任何参数。类和实例都可以调用。 classmethod 在类中需要用到类变量而不需要实例参与的可以这样写 class TestClassMethod(object): a = 0 def __init__(self): TestClassMethod.a += 1 @classmethod def cmethod(cls): print('class method') # 访问a print(cls.a) foo = TestClassMethod() foo.cmethod() TestClassMethod.cmethod() 输出 class method 1 class method 1 [Finished in 0.0s] 类方法可以引用类变量,但被装饰的方法需要传入类对象参数cls,类和实例都可以调用。 总结 class TestClassAndStaticMethod(object): @staticmethod def smethod(*args): print('staticmethod', args) @classmethod def cmethod(*args): print('classmethod', args) foo = TestClassAndStaticMethod() TestClassAndStaticMethod....

March 20, 2017 · 1 min · 107 words · Fython