《Python基础教程(第二版)》学习笔记 -> 第九章 魔法方法、属性和迭代器

准备工作



>>> class NewStyle(object):
more_code_here
>>> class OldStyle:
more_code_here

  在这两个类中,NewStyle是新式的类,OldStyle是旧式的类,如果文件以__metaclass__ = type
开始,那么两个类都是新式类。

  

构造方法



构造方法,当一个对象被创建后,会立即调用构造方法。Python中创建一个构造方法,只要把init方法的名字从简单的init修改成__init__
:

  


>>> class Foobar:
def __init__(self):
self.somevar = 42

>>> f = Foobar()
>>> f.somevar
42

  1. 重写一般方法和特殊的构造方法
    每个类都可能拥有一个或者多个超类,它们会从超类那里继承行为方式。如果一个方法在B类的一个实例中被调用,但在B类中没有找到该方法,那么就会去它的超类A里面找。考虑下面的两个类:

    class A:
    def hello(self):
    print "Hello, A!"

    class B(A):
    pass

    A类定义了一个叫做hello的方法,被B类继承:

    >>> a=A()
    >>> b = B()
    >>> a.hello()
    Hello, A!
    >>> b.hello()
    Hello, A!

    使用这个定义,b.hello()能产生一个不同的结果


    >>> class B(A):
    def hello(self):
    print "B"

    >>> b = B()
    >>> b.hello()
    B

    重写是继承机制中一个重要内容。

    下例:


    class Bird:
    def __init__(self):
    self.hungry = True
    def eat(self):
    if self.hungry:
    print ‘Aaaaah...‘
    self.hungry = False
    else:
    print ‘No thx!‘
    pass

    class SongBird(Bird):
    def __init__(self):

    self.sound = ‘Squawk!‘
    def sing(self):
    print self.sound

    运行:


    >>> sb = SongBird()
    >>> sb.sing()
    Squawk!
    >>> sb.eat()

    Traceback (most recent call last):
    File "<pyshell#2>", line 1, in <module>
    sb.eat()
    File "C:/Users/User/Desktop/Python_Demo/c_3.py", line 5, in eat
    if self.hungry:
    AttributeError: SongBird instance has no attribute ‘hungry‘

    异常很清楚地说明了错误:SongBird没有hungry特性。原因是在SongBird中,构造方法被重写,没有初始化hungry特性的代码。


  2. 调用未绑定的超类构造方法
    写解决上例的问题,代码如下:


    class Bird:
    def __init__(self):
    self.hungry = True
    def eat(self):
    if self.hungry:
    print ‘Aaaaah...‘
    self.hungry = False
    else:
    print ‘No thx!‘
    pass

    class SongBird(Bird):
    def __init__(self):
    Bird.__init__(self) #banding method
    self.sound = ‘Squawk!‘
    def sing(self):
    print self.sound

    运行结果:

    >>> sb = SongBird()
    >>> sb.eat()
    Aaaaah...
    >>> sb.eat()
    No thx!

    为什么会有注意的结果?在调用一个实例的方法时,该方法的self参数会被自动绑定到实例上(这被称为绑定方法)。但如果直接调用类的方法(比如Bird.__init__),那么就没有实例会被绑定。这样就可以自由地提供需要的self参数。这样的方法称为未绑定(unbound)方法。


  3. 使用super函数


    __metaclass__ = type
    class Bird:
    def __init__(self):
    self.hungry = True
    def eat(self):
    if self.hungry:
    print ‘Aaaaah...‘
    self.hungry = False
    else:
    print ‘No thx!‘
    pass

    class SongBird(Bird):
    def __init__(self):
    super(SongBird,self).__init__()
    self.sound = ‘Squawk!‘
    def sing(self):
    print self.sound

    运行结果如下:

    >>> sb = SongBird()
    >>> sb.eat()
    Aaaaah...
    >>> sb.eat()
    No thx!

成员访问



  1. 基本的序列和映射规则
    序列和映射是对象的集合。为了实现它们基本的行为,如果对象是不可变的,那么就需要使用两个魔法方法,如果是可变的则需要使用4个。
    __len__(self):这个方法应该返回集合中所含项目的数量。(序列:返回个数;映射:返回键-值对的数量;返回0,对象会被当做一个布尔变量中的假值进行处理)
    __getitem__(self.key):这个方法返回与所给键对应的值。对于一个序列,键应该是一个0~n-1的整数(也可能是负数,n是序列的长度);对于映射来说,可以使用任何种类的键。
    __setitem__(self,key,value):这个方法应该按一定的方式存储和key相关的value,该值随后可使用__getitem__来获取。
    __delitem__(self,key):这个方法对一部分对象使用del语句时被调用,同事必须删除和元素相关的键。

  2. 子类化列表、字典和字符串

属性



  1. property 函数


    __metaclass__ = type
    class Rectangle:
    def __init__(self):
    self.width = 0
    self.height = 0
    def setSize(self,size):
    self.width,self.height = size
    def getSize(self):
    return self.width,self.height
    size = property(getSize,setSize)

    运行结果:


    >>> r = Rectangle()
    >>> r.width = 10
    >>> r.height = 5
    >>> r.size
    (10, 5)
    >>> r.size = 150,100
    >>> r.height
    100

    size特性仍然取决于getSize和setSize中的计算。

迭代器



  1. 迭代器规则
    迭代的意思是重复做一些事很多次。
    __iter__方法返回一个迭代器(iterator),所谓的迭代器就是具有next方法的对象。在调用next方法时,迭代器会返回它的下一个值。如果next方法被调用,但迭代器没有值可以返回,就会引发一个StopIteration异常。


    class Fibs:
    def __init__(self):
    self.a = 0
    self.b = 1
    def next(self):
    self.a,self.b = self.b,self.a + self.b
    return self.a
    def __iter__(self):
    return self

    fibs = Fibs()
    for f in fibs:
    if f>1000:
    print f
    break


  2. 从迭代器得到序列
    除了在迭代器和可迭代对象上进行迭代外,还能把它们转换为序列:


    class TestIterator:
    value = 0
    def next(self):
    self.value += 1
    if self.value >10:raise StopIteration
    return self.value
    def __iter__(self):
    return self

    运行结果:

    >>> ti = TestIterator()
    >>> list(ti)
    [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

生成器



  生成器也叫简单生成器。

  生成器是一种用普通的函数语法定义的迭代器。

  1. 创建生成器


    >>> nested = [[1,2],[3,4],[5]]
    >>> def flatten(nested):
    for sublist in nested:
    for element in sublist:
    yield element

    >>> for num in flatten(nested):
    print num

    1
    2
    3
    4
    5

    任何包含yield语句的函数称为生成器。


  2. 递归生成器

  3. 通用生成器
    生成器是由两部分组成:生成器的函数和生成器的迭代器。
    生成器的函数是用def语句定义的,包含yield的部分,生成器的迭代器是这个函数的返回部分

  4. 生成器方法

  5. 模拟生成器

(目前难以结合实例来学习,故此文档笔记暂时高于段落,每天开始研究自动化测试,Python核心编程课后习题)

《Python基础教程(第二版)》学习笔记 -> 第九章 魔法方法、属性和迭代器,布布扣,bubuko.com

时间: 2024-07-29 11:45:08

《Python基础教程(第二版)》学习笔记 -> 第九章 魔法方法、属性和迭代器的相关文章

python基础教程第二版读书笔记

第一张 基础知识 模块 import 模块:用函数的时候格式 模块.函数 from 模块 import 函数:用函数的时候格式  函数 字符串 ‘x‘反引号(不是单引号‘’,也可用repr函数),可以将数值x变为字符串,例如x=1,print ”hello“+x(错误),print ”hello“+‘x‘(对的) r-原始字符串,即\将不作为转义符号,例如r”c:\n“ 第二章 列表和元祖(列表可以修改,元祖不能修改) 列表 x=['a',1] y=['b',2] c=[x,y] 索引 0-第一

读书笔记--《Python基础教程第二版》--第2章列表和元组

第二章 列表和元组 2.1 序列的概览 序列:每个元素被分配一个序号  6种:列表.元组.字符串.Unicode字符串.buffer对象.xrange对象         序列可以嵌套序列          python容器的概念:序列.字典.集合 2.2 通用序列的操作 索引.分片.加.乘.属于.长度,最大值.最小值.迭代 2.2.1 索引 >>> greeting='Hello' >>> greeting[0] 'H' >>> greeting[-

读书笔记--《Python基础教程第二版》--第七章 更加抽象

7.1 对象的魔力 多态 不同的类的对象使用同样的操作 封装 继承 7.1.1 多态 1.多态和方法 >>>object.getPrice() >>> 'abc'.count('a') 1 >>> [1,2,'a'].count('a') 1 >>> from random import choice >>> x=choice(['Hello world!',[1,2,'e','e',4]]) >>>

读书笔记--《Python基础教程第二版》-- 第四章 字典:当索引不好用时

字典里的键可以是数字.字符串.元组 4.1 字典的使用 >>> name=['Alice','Beth','Earl'] >>> numbers=['2341','9102','0142'] #电话号码必须使用字符串,二不能是整数,因为电话号码可能以0开头 >>> numbers[name.index('Beth')] '9102' 4.2 创建和使用字典 >>> data ={'title':'My Home Page','text

读书笔记--《Python基础教程第二版》-- 第五章 条件、循环和其他语句

5.1 print和import的更多信息 5.1.1 使用独号输出 >>> print 'Age:',42 Age: 42 >>> 1,2,3 (1, 2, 3) >>> print 1,2,3 1 2 3 >>> print (1,2,3) (1, 2, 3) >>> name='Gumby' >>> greeting='Hello' >>> salutation='Mr.'

读书笔记--《Python基础教程第二版》--第六章 抽象

6.1 懒惰即美德 >>> fibs=[0,1] >>> for i in range(8): ...  fibs.append(fibs[-2]+fibs[-1]) ... >>> fibs [0, 1, 1, 2, 3, 5, 8, 13, 21, 34] 6.2 抽象和结构 page=download_page() freqs=compute_frequencies(page) for word,freq in freqs: print word

Jquery基础教程第二版学习记录

本文仅为个人jquery基础的学习,简单的记录以备忘. 在线手册:http://www.php100.com/manual/jquery/第一章:jquery入门基础jquery知识:jquery能做什么:为什么需要jquery. 第二章:选择符工厂函数$()css选择符属性选择符自定义选择符DOM遍历方法 第三章:事件jQuery.noConflict([extreme]):运行这个函数将变量$的控制权让渡给第一个实现它的那个库.常用方法:(包括键盘,鼠标事件)blur([[data],fn]

《Python基础教程》 读书笔记 第九章 魔法方法、属性和迭代器(上)

构造方法 在Python中创建一个构造方法很容易.只要把init方法的名字从简单的init修改为魔法版本__init__即可: >>> class FooBar: ...     def __init__(self): ...         self.somevar=42 ... >>> f=FooBar() >>> f.somevar 42 给构造方法传几个参数 >>> class FooBar: ...     def __in

&amp;lt;&amp;lt;Python基础教程&amp;gt;&amp;gt;学习笔记 | 第12章 | 图形用户界面

Python支持的工具包非常多.但没有一个被觉得标准的工具包.用户选择的自由度大些.本章主要介绍最成熟的跨平台工具包wxPython.官方文档: http://wxpython.org/ ------ 丰富的平台: Tkinter实际上类似于标准,由于它被用于大多数正式的Python GUI程序.并且它是Windows二进制公布版的一部分. 可是在UNIX上要自己编译安装. 还有一个越来越受欢迎的工具是wxPython. 这是个成熟并且特性丰富的包,也是Python之父,Guido van Ro