Python 2.7 类(二)(完结)

5 继承

继承语法

# 定义类
class C:
    pass
    
# 继承类
class CC(C):
    pass

# 继承模块类
class CCC(inheritance.MC):
    pass

在解析属性引用时,如果请求属性没有在类中被找到,将会在基类中继续搜索。如果基类从其它类中派生而来,此过程会被递归应用。

派生类会重写基类方法。由于在调用相同对象中的其他方法时,方法没有特别的权限,所以一个基类的方法在调用定义在相同基类中的其他方法时,可能会调用到重写此方法的派生类中的方法。

派生类重写基类方法

# 定义基类
class MC:
    def fff(self):
        print "This is MC"
        
# 定义派生类(扩展基类方法)
class CC(MC):
    def fff(self):
        MC.fff(self)
        print "This is Cc"

判断继承内置函数

# 判断实例是否由指定类派生而来
print isinstance(x, int)

# 判断类是否由指定类派生而来
print issubclass(CC, MC)
5.1 多重继承

Python支持有限形式的多重继承。

import base

class A:
    def aa(self):
        print "This is A"

class B:
    def bb(self):
        print "This is B"

class C(A, B, base.Base):
    def cc(self):
        print "This is C"

与只继承一个类相比,唯一的规则是深度优先,由左到右。
方法解析顺序可以动态改变以支持对super()的协同调用。

由于所有多重继承的情况都表现出菱形关系,所以动态顺序顺序必要的。(至少一个双亲类可以通过由底层类出发的多条路径访问。)
为了防止基类被访问超过一次,动态算法线性化搜索顺序,以一种保持每个类指定的从左到右顺序,只调用每个双亲一次,并且不变(即类可以在不影响其双亲优先度的情况下子类化)的方法达成。

6 私有变量与类局部引用

Python中不存在“私有”实例变量。
Python中有一个通用约定:以下划线为前缀的名称应该被看作是API的非公开部分。

由于存在类私有成员的有效用例(即避免名称与子类中定义的名称冲突),存在对命名修改机制的有限支持。
任何形式为__spam(开头至少两个下划线,结尾最多一个下划线)的标识符会被文本替换为_classname__spam,其中classname是当前类名。只要出现在类定义中,就可以在不考虑标识符句法位置的情况下,完成修改。

命名修改有助于子类重写方法时不会破坏内部类方法调用。

注意,传递给exec()、eval()或execfile()的代码不会将调用者的类视为当前类,这一点类似global语句的效果。

7 碎片补充

# 使用类绑定一组数据名称
class C:
    pass:
c = C()
c.n = 'Jo'
c.j = 123

需要特殊抽象数据类型的一段Python代码可以被传入一个模仿数据类型方法的类。

实例方法对象也具有属性。

# 定义类
class CC:
    def ff(self):
        print "fff"
        
# 实例化
x = CC()

# 获取实例对象
x.ff.im_self

# 获取方法对应的函数对象
x.ff.im_func

8 异常也是类

用户定义的异常由类标识。使用此机制可以创建异常的扩展架构。

# raise语句
class B:
    pass
class C(B):
    pass
class D(C):
    pass

for c in [B, C, D]:
    try:
        raise c()
    except D:
        print "D"
    except C:
        print "C"
    except B:
        print "B"

如果异常与except子句中的类相同或是它是异常的基类,异常与except子句中类兼容。

如果一个未处理异常的错误信息没有被打印,异常的类名将会被打印,然后是冒号与空格,最后是使用内置函数str()转化为字符串的实例。

9 迭代器

迭代过程中,for语句调用容器对象的iter()。此函数返回一个迭代器对象,此对象定义了一次访问容器中一个元素的方法next()。当没有元素时,next()提出了StopIteration异常,此异常告知for循环终止。

在类中添加迭代行为,需要定义__iter__()方法,返回一个具有next()方法的对象,也可以在类中同时定义next(),然后令__iter__()返回self。

class Reverse:

    def __init__(self, data):
        self.data = data
        self.index = len(data)

    def __iter__(self):
        return self

    def next(self):
        if self.index == 0:
            raise StopIteration
        self.index = self.index - 1
        return self.data[self.index]

10 生成器

生成器是创建迭代器的简单有效的工具。它们想常规函数一样使用,但是使用yield语句返回数据。每次调用next(),生成器都会从中断处继续(它会记住所有的数据值与最后执行的语句)。

def reverse(data):
    for index in range(len(data)-1, -1, -1):
        yield data[index]

for char in reverse('sdgaf'):
    print char

生成器会自动创建__iter__()与next()方法。
局部变量与执行状态会在调用之间自动保存。这就省略了self.index与self.data的使用,代码更整洁。
当生成器终止时,它会自动提出一个StopIteration。

11 生成器表达式

一些简单的生成器可以使用类似列表推导的语法编码为表达式,不过使用括号代替方括号。这些表达式被设计为用于生成器通过封闭函数立即使用的情况。生成器表达式比完整的生成器定义更紧凑但功能较少,与等价的列表推导式相比,更具内存友好性。

sum(i * i for i in range(10))

详细教程:Python 2.7 Tutorial

猜你喜欢

转载自blog.csdn.net/qq_32165041/article/details/83267875