python王者归来—学习笔记(15)

继续第十二章 类与对象(多态及多重继承、type和instance、特殊属性__doc__和__name__、特殊方法__str()__、__repr()__、__iter()__)

一、多态。之前已经有说明基类与衍生类有相同方法名称的实例,其实那就是本节欲说明的多态(polymorphism)的基本观念,但是多态的概念是不局限在必须有父子关系的类中的。可以将多态想成方法多功能化,相同的函数名称,放入不同类型的对象可以产生不同的结果:

class Animals():
    def which(self):
        return 'It is animal'

class Dogs(Animals):
    #继承动物类
    def which(self):
        return 'It is dog'

class Monkeys(Animals):
    #继承动物类
    def which(self):
        return 'It is monkey'

def doing(obj):  #可传递不同对象参数的函数
    print(obj.which())    #根据不同对象调用不同方法

#以下为主程序
animal = Animals()
doing(animal)
dog = Dogs()
doing(dog)
monkey = Monkeys()
doing(monkey)

在面向对象的程序设计中,也常会发生一个类继承多个类的应用,此时子类也同时继承了多个类的方法。在这个时候,读者应该了解当多个父类拥有相同名称的方法时,应该先执行哪一个父类的方法。在程序中可用下列语法代表继承多个类:class 类名称(父类名称1, ..., 父类名称n):  

class Grandfather():
    """ 祖父类 """
    def action1(self):
        print("Grandfather")

class Father(Grandfather):
    """ 父亲类 """
    def action2(self):
        print("Father")

class Uncle(Grandfather):
    """ 叔叔类 """
    def action2(self):
        print("Uncle")

class Son(Uncle, Father):
    """ 子类 """
    def action3(self):
        print("Son")

son = Son()
son.action3()
son.action2()  #多继续父类中有同名方法,优先调用在前面定义的父类方法
son.action1()

二、type和instance。可以使用type( )函数得到某一对象变量的类型:

class Grandfather():
    """ 祖父类 """
    pass

class Father(Grandfather):
    """ 父亲类 """
    pass

class Son(Father):
    """ 子类 """
    def action(self):
        pass

grandfather = Grandfather()
father = Father()
son = Son()

print("grandfather对象类型:", type(grandfather))
print("father对象类型:", type(father))
print("son对象类型:", type(son))
print("son对象中acion方法类型:", type(son.action))

isinstance( )函数可以传回对象的类是否属于某一类,它包含2个参数,它的语法如下:isinstance(对象, 类)。如果对象的类是属于第2个参数类或属于第2个参数的子类,则传回True,否则传回False。

三、特殊属性和特殊方法。当设计或是看到别人设计的Python程序时,若是遇到__xx__类的字符串就要特别留意了,这些大多数是特殊属性或方法。

1、文档字符串_doc__。文档字符串的英文原意是文档字符串(docstring),Python鼓励程序设计师在设计函数或类时,尽量为函数或类增加文档的批注,未来可以使用__doc__特殊属性列出此文档批注:

class Myclass:
    '''文档字符串示例
Myclass类别的应用'''
    def __init__(self, x):
        self.x = x
    def printMe(self):
        '''文档字符串示例
Myclass类内printMe方法的应用'''
        print(self.x)


def getMax(x, y):
    '''文档字符串示例
    建议x, y是整数
    这个函数将返回最大值'''
    return x if int(x)>int(y) else y


data = Myclass(100)
data.printMe()
print(data.__doc__)         #打印类对象的文档字符串
print(data.printMe.__doc__) #打印类对象中方法的文档字符串

print(getMax(2, 3))
print(getMax.__doc__)  #打印函数的文档字符串

2、__name__属性。__name__可以判别这个程序是自己执行或是被其他程序import导入当成模块使用。如果程序是自己执行,__name__就是__main__。如果是被import到另一个程序,则__name__是本身的文件名。

if __name__ == '__main__':
    print("It is main routine")

3、__str()__方法。这是类的特殊方法,可以协助返回易读取的字符串:

class A():
    def __init__(self, name):
        self.name = name

class B():
    def __init__(self, name):
        self.name = name

    def __str__(self):
        return "%s" % self.name


a = A('huang')
#类A未定义__str__(),输出内存地址
print(a)
b = B('huang')
#类B有定义__str__(),输出对应字符串
print(b)

4、__repr()__方法。上述类B定义了__str__( )方法后,就得到一个适合阅读的结果了。但是如果我们在Python Shell窗口输入b,一样获得不容易阅读的结果。上述原因是,如果只是在Python Shell窗口输入类变量b,系统是调用__repr__( )方法做响应,为了要获得容易阅读的结果,我们也需定义此方法。定义__repr__( )方法,其实此方法内容与__str__( )相同,所以可以用等号取代。

class B():
    def __init__(self, name):
        self.name = name

    def __str__(self):
        return "%s" % self.name

    __repr__ = __str__

5、__iter__()方法。建立类的时候也可以将类定义成一个迭代对象,类似列表或元组,供for … in循环内使用,这时类需设计next( )方法,取得下一个值,直到达到结束条件,可以使用raise StopIteration(第15章会解说,raise)终止循环

class Fib():
    #Fib序列数
    def __init__(self, max):
        self.max = max

    def __iter__(self):
        self.a = 0
        self.b = 1
        return self

    def __next__(self):
        fib = self.a
        if fib > self.max:
            raise StopIteration
        self.a, self.b = self.b, self.a + self.b
        return fib

for i in Fib(100):
    print(i)

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值