Python语言学习:复杂函数(yield/@property)使用方法、案例应用之详细攻略

yield


       带有 yield 的函数在 Python 中被称之为 generator(生成器)。

yield的作用:就是把一个函数变成一个 generator,带有 yield 的函数不再是一个普通函数,Python 解释器会将其视为一个 generator,调用 fab(5) 不会执行 fab 函数,而是返回一个 iterable 对象!在 for 循环执行时,每次循环都会执行 fab 函数内部的代码,执行到 yield b 时,fab 函数就返回一个迭代值,下次迭代时,代码从 yield b 的下一条语句继续执行,而函数的本地变量看起来和上次中断执行前是完全一样的,于是函数继续执行,直到再次遇到 yield。

       yield是一个关键词,类似return, 不同之处在于,yield返回的是一个生成器。为了精通 yield ,你必须要理解:当你调用这个函数的时候,函数内部的代码并不立马执行 ,这个函数只是返回一个生成器对象,这有点蹊跷不是吗。  那么,函数内的代码什么时候执行呢?当你使用for进行迭代的时候.  现在到了关键点了!  第一次迭代中你的函数会执行,从开始到达 yield 关键字,然后返回 yield 后的值作为第一次迭代的返回值. 然后,每次执行这个函数都会继续执行你在函数内部定义的那个循环的下一次,再返回那个值,直到没有可以返回的。  如果生成器内部没有定义 yield 关键字,那么这个生成器被认为成空的。这种情况可能因为是循环进行没了,或者是没有满足 if/else 条件。


1、生成斐波那契數列


def fab(max):

   n, a, b = 0, 0, 1

   while n < max:

       yield b      # 使用 yield

       print(b, '-   T2、print输出代替yield的用法')

       a, b = b, a + b

       n = n + 1

for n in fab(5):

   print(n)

'''

输出结果:

1

1 -   T2、print输出代替yield的用法

1

1 -   T2、print输出代替yield的用法

2

2 -   T2、print输出代替yield的用法

3

3 -   T2、print输出代替yield的用法

5

5 -   T2、print输出代替yield的用法

'''


@property


@property的作用:@property广泛应用在类的定义中,既能检查参数,又可以用类似属性这样简单的方式来访问类的变量。Python内置的@property装饰器就是负责把一个方法变成属性调用的,可以让调用者写出简短的代码,同时保证对参数进行必要的检查,这样,程序运行时就减少了出错的可能性。


1、@property的实现比较复杂,我们先考察如何使用。把一个getter方法变成属性,只需要加上@property就可以了,此时,@property本身又创建了另一个装饰器@score.setter,负责把一个setter方法变成属性赋值,于是,我们就拥有一个可控的属性操作。


class Student(object):

   @property

   def score(self):

       return self._score

   @score.setter

   def score(self, value):

       if not isinstance(value, int):

           raise ValueError('score must be an integer!')

       if value < 0 or value > 100:

           raise ValueError('score must between 0 ~ 100!')

       self._score = value

>>> s = Student()

>>> s.score = 60 # OK,实际转化为s.set_score(60)

>>> s.score # OK,实际转化为s.get_score()

60

>>> s.score = 9999

Traceback (most recent call last):

 ...

ValueError: score must between 0 ~ 100!

2、神奇的@property,我们在对实例属性操作的时候,就知道该属性很可能不是直接暴露的,而是通过getter和setter方法来实现的。还可以定义只读属性,只定义getter方法,不定义setter方法就是一个只读属性。

    下边的birth是可读写属性,而age就是一个只读属性,因为age可以根据birth和当前时间计算出来。


class Student(object):

   @property

   def birth(self):

       return self._birth

   @birth.setter

   def birth(self, value):

       self._birth = value

   @property

   def age(self):

       return 2015 - self._birth

参考文章

廖雪峰的官方网站——使用@property



其他函数


后期更新……


 


上一篇:Android应用程序框架之Home程序(Launcher)


下一篇:实践:在CentOS7.3部署 keepalived 高可用nginx(负载均衡)