零基础入门学Python(十二)—— 魔法方法(下)

零基础入门学Python(十二)—— 魔法方法(下),第1张

概述零基础入门学Python系列内容的学习目录→\rightarrow→零基础入门学Python系列内容汇总。魔法方法(下)1.构造和析构2.算术运算3.简单定制4.属性访问5.描述符6.

零基础入门学Python系列内容的学习目录 → \rightarrow →零基础入门学Python系列内容汇总。

魔法方法(下) 1. 构造和析构2. 算术运算3. 简单定制4. 属性访问5. 描述符6. 定制序列7. 迭代器8. 生成器

  需要学习的基础知识有:构造和析构、算术运算、简单定制、属性访问、描述符、定制序列、迭代器、生成器等。因本部分内容较多,故分为上下两个篇章。
    1、2、3部分内容见零基础入门学Python(十二)—— 魔法方法(上)
    4、5、6、7、8部分内容见零基础入门学Python(十二)—— 魔法方法(下)

1. 构造和析构 2. 算术运算 3. 简单定制

  前半部分内容见零基础入门学Python(十二)—— 魔法方法(上)。

4. 属性访问

  通常可以通过点(.) *** 作符的形式去访问对象的属性,之前也学过如何通过几个BIF适当地去访问属性:

  example1: >>> class C:
           def _ _ init _ _ (self):
             self.x = ‘X-man’

       >>> c = C()
       >>> c.x
       ‘X-man’
       >>> getattr(c,‘x’,'没有这个属性‘)
       ‘X-man’
       >>> getattr(c,‘y’,'没有这个属性‘)
       ‘没有这个属性’
       >>> setattr(c, ‘y’, ‘Yellow’)
       ‘Yellow’
       >>> delattr(c, ‘x’)
       >>> c.x
       Traceback(most recent call last):
        file"<pyshell#18>",line 1,in< module >
         c.X
       AttributeBrror:'C’object has no attribute ‘x’

  然后还有一个叫作property()函数的用法,这个property()使得我们可以用属性去访问属性:

class C:    def __init__(self,size=10):        self.size = size    def getSize(self):        return self.size    def setSize(self,value):        self.size= value    def delSize(self):        del self.size    x= property(getSize, setSize, delSize)

  运行程序:
  >>c=C()
  >>>c.x
  10
  >>> c.x = 12
  >>> c.x
  12
  >>> c.size
  12
  >>> del c.x
  >>> c.size
  Traceback (most recent call last):
    file “<pyshell#75>”, line 1, in < module >
     c.size
  AttributeError: ‘C’ object has no attribute ‘size’

  关于属性访问,我们也可以通过对相应的魔法方法的重写来控制对象的属性访问。表3列举了属性相关的魔法方法。

表3 属性相关的魔法方法
魔法方法含义
_ _ getattr _ _(self, name)定义当用户试图获取一个不存在的属性时的行为
_ _ getattribute _ _(self, name)定义当该类的属性被访问时的行为
_ _ setattr _ _(self,name,value)定义当一个属性被设置时的行为
_ _ delattr _ _(self,name)定义当一个属性被删除时的行为
5. 描述符

  用一句话来解释描述符就是将某种特殊类型的类的实例指派给另一个类的属性。特殊类型的类就是至少要在这个类里边定义_ _get_ _()_ _set_ _()_ _delete_ _()三个特殊方法中的任意一个。表4列举了描述符相关的魔法方法。

表4 描述符相关的魔法方法
魔法方法含义
_ _ get _ _(self,instance,owner)用于访问属性,它返回属性的值
_ _ set _ _(self,instance,value)将在属性分配 *** 作中调用,不返回任何内容
_ _ delete _ _(self,instance)控制删除 *** 作,不返回任何内容
6. 定制序列

  协议(Protocol)与其他编程语言中的接口很相似,它规定哪些方法必须要定义,在Python 中协议更像是一种指南。
  在Python中,像序列类型(如列表、元组、字符串)或映射类型(如字典)都是属于容器类型。
  定制容器有关的一些协议:

如果希望定制的容器是不可变的话,只需要定义 _ _len_ _()_ _getitem_ _() 方法。如果希望定制的容器是可变的话,除了 _ _len_ _()_ _getitem_ _()方法,还需定义_ _setitem_ _()_ _delitem_ _()两个方法。

  表5列举了定制容器类型相关的魔法方法及含义。

表5 定制容器类型相关的魔法方法
魔法方法含义
_ _ len _ _(self)定义当被len()函数调用时的行为(返回容器中元素的个数)
_ _ getitem _ _(self,key)定义获取容器中指定元素的行为,相当于self[key]
_ _ setitem _ _(self,key,value)定义设置容器中指定元素的行为,相当于self[key]=value
_ _ delitem _ _(self,key)定义删除容器中指定元素的行为,相当于del self[key]
_ _ iter _ _(self)定义当迭代容器中的元素的行为
_ _ reversed _ _(self)定义当被reversed()函数调用时的行为
_ _ contains _ _(self,item)定义当使用成员测试运算符(in或not in)时的行为
7. 迭代器

  迭代的意思类似于循环,每一次重复的过程被称为一次法代的过程。而每一次迭代得到的结果会被用来作为下一次迭代的初始值。提供迭代方法的容器称为迭代器,通常接触的迭代器有序列(列表、元组、字符串)还有字典,都支持迭代的 *** 作。
  举个例子,通常使用for语句来进行迭代:

  example1: >>> for i in “Python”:
           print(i)

        P
        y
        t
        h
        o
        n

  字符串就是一个容器,同时也是一个迭代器,for语句的作用就是触发这个迭代器的迭代功能,每次从容器里依次拿出一个数据,这就是迭代 *** 作。
  字典和文件也是支持迭代 *** 作的:

  example2: >>> links={‘A’: ‘a’, \
               ‘B’: ‘b’, \
               ‘C’: ‘c’, \
               ‘D’: ‘d’}
        >>> for each in links:
           print(’%s -> %s’ %(each, links[each]))

        A -> a
        B -> b
        C -> c
        D -> d

  关于迭代,Python提供了两个BIF: iter()next()
  对一个容器对象调用iter()就得到它的迭代器,调用next()迭代器就会返回下一个值,如果进代器没有值可以返回了,Python会抛出一个叫作Stoplteration的异常:

  example3: >>> string=“Python”
        >>> it= iter(string)
        >>> next(it)
        ‘P’
        >>> next(it)
        ‘y’
        >>> next(it)
        ‘t’
        >>> next(it)
        ‘h’
        >>> next(it)
        ‘o’
        >>> next(it)
        ‘n’
        >>> next(it)
        Traceback (most recent call last):
          file “<pyshell#23>”, line 1, in < module >
            next(it)
        stopiteration

  关于实现迭代器的魔法方法有两个_ _ iter_ _()_ _next_ _()
  一个容器如果是迭代器,那就必须实现_ _ iter_ _()魔法方法,这个方法实际上就是返回迭代器本身。而_ _next_ _()魔法方法决定了迭代的规则。看个例子:

class Fibs:    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        return self.a

  运行程序:
  >>> fibs = Fibs()
  >>> for each in fibs:
       if each<20:
         print(each)
       else:
         break

  1
  1
  2
  3
  5
  8
  13

  但是迭代器没有终点,所以如果没有跳出循环,它会不断进代下去,这时就需要我们加一个参数,用于控制迭代的范围。

class Fibs:    def __init__(self, n = 20):        self.a =0        self.b =1        self.n = n    def __iter__(self):        return self    def __next__(self):        self.a,self.b = self.b,self.a + self.b        if self.a > self.n:            raise stopiteration        return self.a

  运行程序:
  >>> fibs = Fibs(10)
  >>> for each in fibs:
       print(each)

  1
  1
  2
  3
  5
  8

8. 生成器

  生成器其实就是迭代器的一种实现,生成器的发明有几个方面好处:

一方面可以使得Python更为简洁,迭代器需要我们自己去定义一个类和实现相关的方法,而生成器则只需要在普通的函数中加上一个yIEld语句即可。在另一个更重要的方面,使得Python模仿协同程序的概念得以实现。所谓协同程序,就是可以运行的独立函数调用,函数可以暂停或者挂起,并在需要的时候从程序离开的地方继续或者重新开始。 总结

以上是内存溢出为你收集整理的零基础入门学Python(十二)—— 魔法方法(下)全部内容,希望文章能够帮你解决零基础入门学Python(十二)—— 魔法方法(下)所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/langs/1186143.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-03
下一篇 2022-06-03

发表评论

登录后才能评论

评论列表(0条)

保存