面向对象,多态与多态性

1. 如何是多态

面向对象学习目录

python进阶(6):多态,封装,python进阶

前些天说了面向对象三大特点的接轨,明天以来多态和打包,比超多别样程序猿说python不辅助多态未有多态,而不是python未有多态,而是python四处皆多态。明天的上书珍视会放在封装。

 

一、多态

1、多态

多态指的是一类东西有多样形象

水有三种形状:冰 水雾 水

星彩网app下载,动物有二种形态:人,狗,猪

星彩网app下载 1

import abc
class Animal(metaclass=abc.ABCMeta): #同一类事物:动物
    @abc.abstractmethod
    def talk(self):
        pass

class People(Animal): #动物的形态之一:人
    def talk(self):
        print('say hello')

class Dog(Animal): #动物的形态之二:狗
    def talk(self):
        print('say wangwang')

class Pig(Animal): #动物的形态之三:猪
    def talk(self):
        print('say aoao')

多态

文本有各个模样:文本文件,可实施文件

星彩网app下载 2

import abc
class File(metaclass=abc.ABCMeta): #同一类事物:文件
    @abc.abstractmethod
    def click(self):
        pass

class Text(File): #文件的形态之一:文本文件
    def click(self):
        print('open file')

class ExeFile(File): #文件的形态之二:可执行文件
    def click(self):
        print('execute file')

文件

2、多态性

多态性是指在不思量实例类型的处境下利用实例

在面向对象方法中貌似是那样表述多态性:

向分裂的靶子发送同一条音信,不相同的靶子在收受时会产生区别的行为(即方法)。也正是说,种种对象足以用自身的办法去响应协同的音讯。所谓音讯,正是调用函数,差别的表现正是指分裂的贯彻,即举办不一样的函数。

诸如:老师.下课铃响了(),学子.下课铃响了(卡塔尔(英语:State of Qatar),老师试行的是下班操作,学生实践的是放学操作,固然双方音信无差别于,可是进行的法力区别

星彩网app下载 3

peo=People()
dog=Dog()
pig=Pig()

#peo、dog、pig都是动物,只要是动物肯定有talk方法
#于是我们可以不用考虑它们三者的具体是什么类型,而直接使用
peo.talk()
dog.talk()
pig.talk()

#更进一步,我们可以定义一个统一的接口来使用
def func(obj):
    obj.talk()

多态性

3、钻水鸭类型

Python崇尚绒鸭类型,即‘假使看起来像、叫声音图像何况走起路来像钻水鸭,那么它正是硬尾鸭’python程序猿平常依照这种表现来编写程序。举个例子,假诺想编写现存对象的自定义版本,能够世襲该指标也得以创建一个外观和表现像,但与它无任何关系的全新对象,前面一个经常用于保存程序组件的松耦合度。

例1:利用标准库中定义的各个‘与公事相符’的目的,固然那一个指标的劳作措施像文件,但她们从没持续内置文件对象的点子

例2:类别类型有二种形象:字符串,列表,元组,但他俩一直未有一贯的持续关系

星彩网app下载 4例子


 

二、封装

卷入:遮掩对象的属性和促成细节,仅对外提供公共访谈格局。

好处:

1、 将调换隔断; 

2.、便于使用;

3.、提升复用性; 

4.、升高安全性;

装进原则:

1、 将无需对外提供的剧情都遮盖起来;

2、 把品质都规避,提供公共措施对其访谈。

1、私有变量

星彩网app下载 5

#其实这仅仅这是一种变形操作
#类中所有双下划线开头的名称如__x都会自动变形成:_类名__x的形式:

class A:
    __N=0 #类的数据属性就应该是共享的,但是语法上是可以把类的数据属性设置成私有的如__N,会变形为_A__N
    def __init__(self):
        self.__X=10 #变形为self._A__X
    def __foo(self): #变形为_A__foo
        print('from A')
    def bar(self):
        self.__foo() #只有在类内部才可以通过__foo的形式访问到.

#A._A__N是可以访问到的,即这种操作并不是严格意义上的限制外部访问,仅仅只是一种语法意义上的变形

个人变量

特点:

1、类中定义的__x只好在在那之中使用,如self.__x,援用的正是变形的结果。

2、这种变形其实正是针对外界的变形,在外界是力不能支透过__x那一个名字访谈到的。

3、在子类定义的__x不会覆盖在父类定义的__x,因为子类中变产生了:_子类名__x,而父类中变变成了:_父类名__x,即双下滑线初阶的性质在一而再三番两遍给子类时,子类是力不能支隐蔽的。

注意:

这种体制也并未当真意义上限定大家从外表直接访谈属性,知道了类名和属性名就能够拼有名字:_类名__质量,然后就足以访谈了,如a._A__N

2、私有方法

在继续中,父类假诺不想让子类覆盖自个儿的点子,能够将艺术定义为私有的

 

星彩网app下载 6

#正常情况
class A:
    def fa(self):
         print('from A')
    def test(self):
        self.fa()

class B(A):
     def fa(self):
         print('from B')

b=B()
b.test()
#from B


#把fa定义成私有的,即__fa
class A:
     def __fa(self): #在定义时就变形为_A__fa
         print('from A')
     def test(self):
         self.__fa() #只会与自己所在的类为准,即调用_A__fa

class B(A):
     def __fa(self): #在定义时就变形为_B__fa
         print('from B')

b=B()
b.test()
#from A

个人方法

 

3、扩展性

封装在于明确区分内外,使得类实现者能够改正封装内的东西而不影响外界调用者的代码;而外界使用用者只知道三个接口(函数卡塔尔(英语:State of Qatar),只要接口(函数)名、参数不改变,使用者的代码永久没有需求改动。

星彩网app下载 7

#类的设计者
class Room:
    def __init__(self,name,owner,width,length,high):
        self.name=name
        self.owner=owner
        self.__width=width
        self.__length=length
        self.__high=high
    def tell_area(self): #对外提供的接口,隐藏了内部的实现细节,此时我们想求的是面积
        return self.__width * self.__length


#使用者
r1=Room('卧室','egon',20,20,20)
r1.tell_area() #使用者调用接口tell_area


#类的设计者,轻松的扩展了功能,而类的使用者完全不需要改变自己的代码
class Room:
    def __init__(self,name,owner,width,length,high):
        self.name=name
        self.owner=owner
        self.__width=width
        self.__length=length
        self.__high=high
    def tell_area(self): #对外提供的接口,隐藏内部实现,此时我们想求的是体积,内部逻辑变了,只需求修该下列一行就可以很简答的实现,而且外部调用感知不到,仍然使用该方法,但是功能已经变了
        return self.__width * self.__length * self.__high


#对于仍然在使用tell_area接口的人来说,根本无需改动自己的代码,就可以用上新功能
 r1.tell_area()

扩展性

4、property属性

星彩网app下载 8

'''
例一:BMI指数(bmi是计算而来的,但很明显它听起来像是一个属性而非方法,如果我们将其做成一个属性,更便于理解)

成人的BMI数值:
过轻:低于18.5
正常:18.5-23.9
过重:24-27
肥胖:28-32
非常肥胖, 高于32
  体质指数(BMI)=体重(kg)÷身高^2(m)
  EX:70kg÷(1.75×1.75)=22.86
'''
class People:
    def __init__(self,name,weight,height):
        self.name=name
        self.weight=weight
        self.height=height
    @property
    def bmi(self):
        return self.weight / (self.height**2)

p1=People('egon',75,1.85)
print(p1.bmi)

BMI指数 星彩网app下载 9

import math
class Circle:
    def __init__(self,radius): #圆的半径radius
        self.radius=radius

    @property
    def area(self):
        return math.pi * self.radius**2 #计算面积

    @property
    def perimeter(self):
        return 2*math.pi*self.radius #计算周长

c=Circle(10)
print(c.radius)
print(c.area) #可以像访问数据属性一样去访问area,会触发一个函数的执行,动态计算出一个值
print(c.perimeter) #同上
'''
输出结果:
314.1592653589793
62.83185307179586
'''
#注意:此时的特性area和perimeter不能被赋值
c.area=3 #为特性area赋值
'''
抛出异常:
AttributeError: can't set attribute
'''

圆的周长和面积

将三个类的函数定义成特征未来,对象再去行使的时候obj.name,根本不可能察觉本人的name是执行了一个函数然后总计出来的,这种个性的应用方法信守了归并访问的尺度

。。。

(剩余后天昂首挺立立异)

 

 

 

 

 

前几日说了面向对象三大特点的接轨,几眼前以来多态和打包,超级多其余程序猿说python不协理多态未有...

1 接口与归风度翩翩化设计

    多态指的是均等种/类东西的例外形态

1 面向对象介绍

1.1 归一化概念:

  归大器晚成化的利润:

  1.归生龙活虎化让使用者无需关切对象的类是哪些,只需求领会这么些目的都具有某个意义就足以了,那庞大减弱了使用者的施用难度。

  2.归后生可畏化使得高层的外表使用者能够不加区分的处理全部接口包容的对象集合

 

  世袭的两用

  生机勃勃:世襲基类的方式,並且做出本人改换依旧扩充(代码重用):实施中,世襲的这种用处意义并不十分大,甚至一时是危机的。因为它使得子类与基类现身强耦合。

  二:证明某些子类宽容于某基类,定义叁个接口类(模仿java的Interface),接口类中定义了一些接口名(正是函数名)且未达成接口的效果与利益,子类继传承口类,况兼完成接口中的功用

星彩网app下载 10

class Interface:
    '''
    定义接口Interface类来模仿接口的概念,
    python中压根就没有interface关键字来定义一个接口。
    '''
    def read(self): # 定接口函数read
        pass

    def write(self): # 定义接口函数write
        pass

class Txt(Interface): # 文本,具体实现read和write
    def read(self):
        print('文本数据的读取方法')

    def write(self):
        print('文本数据的读取方法')

class Sata(Interface): #磁盘,具体实现read和write
    def read(self):
        print('硬盘数据的读取方法')

    def write(self):
        print('硬盘数据的读取方法')

class Process(Interface):
    def read(self):
        print('进程数据的读取方法')

    def write(self):
        print('进程数据的读取方法')

t = Txt()
s = Sata()
p = Process()

t.read()    # 运行结果:文本数据的读取方法
s.read()    # 运行结果:硬盘数据的读取方法
p.read()    # 运行结果:进程数据的读取方法

星彩网app下载 11

 

2.为何要用多态性

2 类、实例、属性、方法精解

1.2 抽象类

  领悟知识点

  与java相符,python也许有抽象类的定义不过雷同须要看重模块完成,抽象类是贰个非常的类,它的非常之处在于只好被持续,不能够被实例化

  凭仗abc模块,实行效仿抽象类

星彩网app下载 12

import abc
class Interface(metaclass=abc.ABCMeta):
    '''
    定义接口Interface类来模仿接口的概念,
    python中压根就没有interface关键字来定义一个接口。
    '''
    @abc.abstractmethod
    def read(self): # 定接口函数read
        pass
    @abc.abstractmethod
    def write(self): # 定义接口函数write
        pass

class Txt(Interface): # 文本,具体实现read和write
    def read(self):
        pass

    def write(self):
        pass

t = Txt()

星彩网app下载 13

 

  1 扩张了前后相继的狡滑

3 面向进度与面向对象进一层相比

1.3 多态

  面向对象的多态、多态性

  多态:指的是生龙活虎律种东西的有余造型

  动物有二种样子:人、狗、猪

星彩网app下载 14

# 多态:同一种事物的多种形态
class Animal: # 同一类事物:动物
    def talk(self):
        pass

class People(Animal): # 动物的形态之一:人
    def talk(self):
        print('say hello')

class Dog(Animal): # 动物的形态之二:狗
    def talk(self):
        print('say wangwang')

p=People()
d=Dog()
p.talk()
d.talk()

星彩网app下载 15

 

  2 充实了程序的可扩张性

4 类与对象

1.4 多态性

  多态性:能够在不考虑实例类型的前提下采纳实例

星彩网app下载 16

# 多态:同一种事物的多种形态
class Animal: # 同一类事物:动物
    def talk(self):
        pass

class People(Animal): # 动物的形态之一:人
    def talk(self):
        print('say hello')

class Dog(Animal): # 动物的形态之二:狗
    def talk(self):
        print('say wangwang')

# 多态性:可以在不考虑实例类型的前提下使用实例
p=People()
d=Dog()

def Talk(animal):
    animal.talk()

Talk(p)
Talk(d)

星彩网app下载 17

 

多态性:分为静态多态性和动态多态性

5 属性查找与绑定方法

1.5 多态性的好处

  多态性的裨益:

  1.日增了前后相继的圆滑

  2.日增了前后相继可扩充性

 

    多态性:在多态的背景下,能够在并不是思考对象实际品种的前提下而一向行使对象

6 小结

1.6 秋沙鸭类型

  Python崇尚树鸭类型,即‘假如看起来像、叫声像并且走起路来像赤麻鸭,那么它正是海番鸭’

  python程序员通常依据这种行为来编写程序。举个例子,即使想编写现存对象的自定义版本,能够继续该目的

  也足以创建一个外观和表现像,但与它无其余涉及的全新对象,前者经常用于保存程序组件的松耦合度。

  利用标准库中定义的各类‘与公事雷同’的对象,就算那个目的的劳作章程像文件,但她俩从没持续内置文件对象的章程

星彩网app下载 18

# 二者都像鸭子,二者看起来都像文件,因而就可以当文件一样去用
class TxtFile:
    def read(self):
        pass

    def write(self):
        pass

class DiskFile:
    def read(self):
        pass
    def write(self):
        pass

星彩网app下载 19

 

    多态性的精髓:统黄金时代

7 世襲与派生

2 封装

3. 什么用多态

8 组合

2.1 隐藏

  在python中用双下划线起首的主意将质量隐敝起来

星彩网app下载 20

class Foo:
    __N = 1111 # _Foo__N
    def __init__(self,name):
        self.__Name=name # self._Foo__Name=name

    def __f1(self): # _Foo__f1
        print('f1')
    def f2(self):
        self.__f1() # self._Foo__f1()

f = Foo('egon')
# print(f.__N)   # 把数据类型隐藏起来了

# 这种隐藏需要注意的问题:
# 1:这种隐藏只是一种语法上变形操作,并不会将属性真正隐藏起来
print(Foo.__dict__)
print(f.__dict__)    # 运行结果:{'_Foo__Name': 'egon'}
print(f._Foo__Name)  # 运行结果:egon
print(f._Foo__N)     # 运行结果:1111

# 2:这种语法级别的变形,是在类定义阶段发生的,并且只在类定义阶段发生
Foo.__x = 123123
print(Foo.__dict__)  # 运行结果:...'__doc__': None, '__x': 123123}
print(Foo.__x)       # 运行结果:123123
f.__x = 123123123
print(f.__dict__)    # 运行结果:{'_Foo__Name': 'egon', '__x': 123123123}
print(f.__x)         # 运行结果:123123123

# 3:在子类定义的__x不会覆盖在父类定义的__x,因为子类中变形成了:_子类名__x,
# 而父类中变形成了:_父类名__x,即双下滑线开头的属性在继承给子类时,

# 子类是无法覆盖的。
class Foo:
    def __f1(self): # _Foo__f1
        print('Foo.f1')

    def f2(self):
        self.__f1() # self._Foo_f1

class Bar(Foo):
    def __f1(self): # _Bar__f1
        print('Bar.f1')

b = Bar()
b.f2()    # 运行结果:Foo.f1

星彩网app下载 21

 

class Animal:
    def speak(self):
        pass
class People(Animal):
    def shuo(self):
        print('say hello')
class Dog(Animal):
    def jiao(self):
        print('汪汪汪')
class Pig(Animal):
    def chang(self):
        print('哼哼哼')
obj1=People()
obj2=Dog()
obj3=Pig()
# obj1.speak()
# obj2.speak()
# obj3.speak()
def speak(animal):
    animal.speak()
speak(obj1)
speak(obj2)
speak(obj3)

9 抽象类

2.2 封装数据属性

星彩网app下载 22

# 封装不是单纯意义的隐藏
# 1:封装数据属性:将属性隐藏起来,然后对外提供访问属性的接口,
# 关键是我们在接口内定制一些控制逻辑从而严格控制使用对数据属性的使用
class People:
    def __init__(self,name,age):
        if not isinstance(name,str):
            raise TypeError('%s must be str' %name)
        if not isinstance(age,int):
            raise TypeError('%s must be int' %age)
        self.__Name=name
        self.__Age=age
    def tell_info(self):
        print('<名字:%s 年龄:%s>' %(self.__Name,self.__Age))

    def set_info(self,x,y):
        if not isinstance(x,str):
            raise TypeError('%s must be str' %x)
        if not isinstance(y,int):
            raise TypeError('%s must be int' %y)
        self.__Name=x
        self.__Age=y

p=People('egon',18)
p.tell_info()       # 运行结果:<名字:egon 年龄:18>

p.set_info('Egon',19)
p.tell_info()       # 运行结果:<名字:egon 年龄:19>

星彩网app下载 23

 

python 崇尚海番鸭类型

10 多态

2.3 封装函数属性

  封装函数属性的目标:隔开分离复杂度

星彩网app下载 24

# 2:封装函数属性:为了隔离复杂度
# 取款是功能,而这个功能有很多功能组成:插卡、密码认证、输入金额、打印账单、取钱
# 对使用者来说,只需要知道取款这个功能即可,其余功能我们都可以隐藏起来,很明显这么做
# 隔离了复杂度,同时也提升了安全性

class ATM:
    def __card(self):
        print('插卡')
    def __auth(self):
        print('用户认证')
    def __input(self):
        print('输入取款金额')
    def __print_bill(self):
        print('打印账单')
    def __take_money(self):
        print('取款')

    def withdraw(self):
        self.__card()
        self.__auth()
        self.__input()
        self.__print_bill()
        self.__take_money()

a = ATM()
a.withdraw()
# 运行结果:
#       插卡
#       用户认证
#       输入取款金额
#       打印账单
#       取款

星彩网app下载 25

 

逗比每十四日:

11 封装

2.4 静态属性

星彩网app下载 26

class Foo:
    @property
    def f1(self):
         print('Foo.f1')

f = Foo()
f.f1        # 运行结果:Foo.f1

星彩网app下载 27

  示例:计算BMI指数

星彩网app下载 28

'''
例:BMI指数(bmi是计算而来的,但很明显它听起来像是一个属性而非方法,
如果我们将其做成一个属性,更便于理解)
成人的BMI数值:
过轻:低于18.5
正常:18.5-23.9
过重:24-27
肥胖:28-32
非常肥胖, 高于32
  体质指数(BMI)=体重(kg)÷身高^2(m)
  EX:70kg÷(1.75×1.75)=22.86
'''
class People:
    def __init__(self,name,weight,height):
        self.name=name
        self.weight=weight
        self.height=height
    @property
    def bmi(self):
        return self.weight / (self.height**2)

p=People('jack',75,1.80)
p.height=1.86
print(p.bmi)

星彩网app下载 29

 

  Python崇尚绒鸭类型,即‘如若看起来像、叫声音图像而且走起路来像绿头鸭,那么它就是潜水鸭’

12 绑定方法与非绑定方法

3 面向对象高等

python程序猿经常依据这种行为来编写程序。举个例子,若是想编写现成对象的自定义版本,能够持续该目的

13 内置方法(上)

3.1 反射

  通过字符串,反射到真实的性质上,找到真正的性质

星彩网app下载 30

class Foo:
    x=1
    def __init__(self,name):
        self.name = name

    def f1(self):
        print('from f1')

print(Foo.x) # Foo.__dict__['x']

f = Foo('egon')
print(f.__dict__)

print(f.name)
print(f.__dict__['name'])

# hasattr
print(hasattr(f,'name'))    # f.name
print(hasattr(f,'f1'))      # f.f1
print(hasattr(f,'x'))       # f.x

# setattr
setattr(f,'age',18)         # f.age=18

# getattr
print(getattr(f,'name'))      # f.name
print(getattr(f,'abc',None))  # f.abc
print(getattr(f,'name',None)) # f.abc

func = getattr(f,'f1')  # f.f1
func()

# delattr
delattr(f,'name')    # del f.name
print(f.__dict__)

星彩网app下载 31

 

也足以创设八个外观和作为像,但与它无其余关联的全新对象,前面一个日常用于保存程序组件的松耦合度。

14 内置方法(中)之描述符

3.2 item系列

  Item系类,主要归纳:__getitem__、__setitem__、 __delitem__,通过那多少个item,能够像操作字典相符,操作对象的性质。

星彩网app下载 32

class Foo:
    def __getitem__(self, item):
        print('=====>get')
        return self.__dict__[item]

    def __setitem__(self, key, value):
        self.__dict__[key]=value
        # setattr(self,key,value)

    def __delitem__(self, key):
        self.__dict__.pop(key)

f = Foo()
f['name'] = "jack"   # 设置
print(f["name"])      # 取出属性
del f["name"]        # 删除
print(f.__dict__)

星彩网app下载 33

 

例1:利用标准库中定义的各个‘与公事雷同’的指标,尽管那些目的的做事办法像文件,但他俩从没持续内置文件对象的点子

15 内置方法(下)

3.3 __str__

  通过__str__,打字与印刷对象消息

星彩网app下载 34

class People:
    def __init__(self,name,age,sex):
        self.name=name
        self.age=age
        self.sex=sex

    def __str__(self): # 在对象被打印时触发执行
        return '<name:%s age:%s sex:%s>' %(self.name,self.age,self.sex)

p=People('alex',38,'male')
print(p)    # 运行结果:<name:alex age:38 sex:male>

星彩网app下载 35

 

星彩网app下载 36星彩网app下载 37

16 元类

3.4 析构方法

  用法:清理一些能源,清理一些python深入剖判器无法清理的能源,比方:清理操作系统的能源,张开文件,向操作系统一发布起调用,关闭文件句柄能源

星彩网app下载 38

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

    def __del__(self): # 在对象资源被释放时触发
        print('-----del------')

f = Foo("mary")
del f
print('对象被释放')

星彩网app下载 39

 

class Disk:
    def read(self):
        print('Disk read')

    def write(self):
        print('Disk write')


class Memory:
    def read(self):
        print('Mem read')

    def write(self):
        print('Mem write')
obj1=Disk()
obj2=Memory()

obj1.read()
obj2.read()

4 异常

星彩网app下载 40

# 逻辑错误
# TypeError
for i in 3:
    pass

# NameError
aaaaa

# ValueError
int('asdfsadf')

# IndexError
l=[1,2]
l[1000]

#KeyError
d = {'a':1}
d['b']

# AttributeError
class Foo:pass
Foo.x

星彩网app下载 41

 

View Code

多态

  抽象类统意气风发标准了风姿洒脱部分类似类的日常天性后,世襲该抽象类的依次子类的具体表现情势是足以五种种种的(具体展现为:数码属性的值各不同、函数属性的函数体各不同)

  多态指的是生机勃勃类东西有多种形状,举例

  动物有各个形象:人,狗,猪

 1 import abc
 2 
 3 class Animal(metaclass=abc.ABCMeta): #同一类事物:动物
 4     @abc.abstractmethod
 5     def talk(self):
 6         pass
 7  
 8 class People(Animal): #动物的形态之一:人
 9     def talk(self):
10         print('say hello')
11  
12 class Dog(Animal): #动物的形态之二:狗
13     def talk(self):
14         print('say wangwang')
15  
16 class Pig(Animal): #动物的形态之三:猪
17     def talk(self):
18         print('say aoao')

 

文本有多样模样:文本文件,可施行文件

 1 import abc
 2 class File(metaclass=abc.ABCMeta): #同一类事物:文件
 3     @abc.abstractmethod
 4     def click(self):
 5         pass
 6  
 7 class Text(File): #文件的形态之一:文本文件
 8     def click(self):
 9         print('open file')
10  
11 class ExeFile(File): #文件的形态之二:可执行文件
12     def click(self):
13         print('execute file')

 

4.1 万分管理

  倘诺不当产生的基准可预言的,大家供给用if实行拍卖,在错误发生早前开展防范

  借使不当发生的尺度时不足预言的,则须要用到try…except,在错误产生以往举行拍卖

星彩网app下载 42

#基本语法为
try:
    # 被检测的代码块
except 异常类型:
    # try中一旦检测到异常,就执行这个位置的逻辑
# 示例
try:
    f=open('a.txt')
    g=(line.strip() for line in f)
    print(next(g))
    print(next(g))
except StopIteration:
    f.close()

星彩网app下载 43

 

 

多态性

生龙活虎、什么是多态动态绑定(在这里起彼伏的背景下使用时,偶然也称为多态性)

  多态性是指在不寻思实例类型的场所下利用实例,多态性分为静态多态性和动态多态性

  静态多态性:如别的类型都足以用运算符 实行演算

  动态多态性:如下

 1 peo=People()
 2 dog=Dog()
 3 pig=Pig()
 4  
 5 #peo、dog、pig都是动物,只要是动物肯定有talk方法
 6 #于是我们可以不用考虑它们三者的具体是什么类型,而直接使用
 7 peo.talk()
 8 dog.talk()
 9 pig.talk()
10  
11 #更进一步,我们可以定义一个统一的接口来使用
12 def func(obj):
13     obj.talk()

所以,总计下抽象类与多态的涉嫌:

  先由抽象类统一定义这个相符类的貌似天性(包蕴数据属性和函数属性,此中分明各相似类必需定义那些函数属性概念的函数体可以多样形状),然后再将平常的函数属性用统生机勃勃的接口归蓬蓬勃勃化调用(统风流罗曼蒂克接口的幼功是各子类都正式要求了概念那一个相像函数属性),从而完结了“同黄金年代接口,各样造型”

 

二、为啥要用多态性(多态性的好处)

  其实大家从上边多态性的例证能够看看,大家并从未扩展哪些新的知识,也正是说python本人便是援助多态性的,这么做的补益是什么样吧?

1.充实了程序的灵活性

  以不改变应万变,无论对象九变十化,使用者都以均等种情势去调用,如func(animal卡塔尔国

2.日增了程序额可扩充性

    通过继承animal类成立了八个新的类,使用者无需校勘自个儿的代码,仍然用func(animal卡塔尔国去调用

>>> class Cat(Animal): #属于动物的另外一种形态:猫... 
        def talk(self):
            ... 
            print('say miao')
            ...

>>> def func(animal): #对于使用者来说,自己的代码根本无需改动
        ... 
        animal.talk()
        ...

>>> cat1=Cat() #实例出一只猫
>>> func(cat1) #甚至连调用方式也无需改变,就能调用猫的talk功能
say miao

'''
这样我们新增了一个形态Cat,由Cat类产生的实例cat1,使用者可以在完全不需要修改自己代码的情况下。使用和人、狗、猪一样的方式调用cat1的talk方法,即func(cat1)
'''

 

4.2 多分支非凡

星彩网app下载 44

try:
    aaaa
    print('====>1')
    l = []
    l[3]
    print('====>2')
    d = {}
    d['x']
    print('====>3')
except NameError as e:
    print(e)
except IndexError as e:
    print(e)
except KeyError as e:
    print(e)

星彩网app下载 45

 

钻水鸭类型

逗比时刻:

        Python崇尚硬尾鸭类型,即‘要是看起来像、叫声像並且走起路来像红鸭,那么它就是绿头鸭’

        python程序猿平日依照这种行为来编写程序。比方,要是想编写现存对象的自定义版本,能够持续该目的

        也足以创制一个外观和表现像,但与它无其余关联的全新对象,后面一个常常用于保存程序组件的松耦合度。

 

例1:使用标准库中定义的各个‘与公事形似’的指标,固然那几个指标的劳作办法像文件,但她俩并未有持续内置文件对象的法子

 1 #二者都像鸭子,二者看起来都像文件,因而就可以当文件一样去用
 2 class TxtFile:
 3     def read(self):
 4         pass
 5  
 6     def write(self):
 7         pass
 8  
 9 class DiskFile:
10     def read(self):
11         pass
12     def write(self):
13         pass

 

例2:队列类型有多样形象:字符串,列表,元组,但他们直接未有一直的一连关系

 1 #str,list,tuple都是序列类型
 2 s=str('hello')
 3 l=list([1,2,3])
 4 t=tuple((4,5,6))
 5  
 6 #我们可以在不考虑三者类型的前提下使用s,l,t
 7 s.__len__()
 8 l.__len__()
 9 t.__len__()
10  
11 len(s)
12 len(l)
13 len(t)

 

4.3 万能可怜

星彩网app下载 46

try:
    # aaaa
    print('====>1')
    l = []
    l[3]
    print('====>2')
except Exception as e:
    print(e)

星彩网app下载 47

 

4.4 基本布局

星彩网app下载 48

try:
    aaaa
    print('====>1')
    l=[]
    l[3]
    print('====>2')
    d={}
    d['x']
    print('====>3')
except NameError as e:
    print(e)
except IndexError as e:
    print(e)
except KeyError as e:
    print(e)
except Exception as e:
    print(e)
else:
    print('在没有错误的时候执行')
finally:
    print('无论有无错误,都会执行')

星彩网app下载 49

 

4.5 自定义格外

星彩网app下载 50

class EgonException(BaseException):
    def __init__(self, msg):
        self.msg=msg
    def __str__(self):
        return '<%s>' %self.msg

raise EgonException('jack 的异常')

星彩网app下载 51

 

5 Socket编程

  IP 端口,标记唯黄金时代二个软件、应用

  tcp是基于链接的,必须先运营服务端,然后再开发银行客商端去链接服务端

5.1 轻巧套接字

5.1.1 服务端

星彩网app下载 52

import socket

# 买手机
phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

# 插卡
phone.bind(("127.0.0.1", 8080))

# 开机
phone.listen(5)

# 等待电话
print("server start...")
conn,client_addr = phone.accept()  # tcp链接,client_addr
print("链接", conn)
print(client_addr)

# 基于建立的链接,收发消息
client_data = conn.recv(1024)
print("客户端的消息", client_data)
conn.send(client_data.upper())

# 挂电话链接
conn.close()

# 关机
phone.close()

星彩网app下载 53

 

5.1.2 客户端

星彩网app下载 54

import socket
phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
phone.connect(("127.0.0.1", 8080))

phone.send("hello".encode("utf-8"))
server_data = phone.recv(1024)
print("服务端回应的消息", server_data)
phone.close() 

星彩网app下载 55

 

5.2 加上通讯循环

5.2.1 服务端

星彩网app下载 56

import socket

phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
phone.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
phone.bind(("127.0.0.1", 8080))
phone.listen(5)
print("server start...")
conn,client_addr = phone.accept()

while True: # 通讯循环
    client_data = conn.recv(1024)
    print("客户端的消息", client_data)
    conn.send(client_data.upper())

conn.close()
phone.close()

星彩网app下载 57

 

5.2.2 客户端

星彩网app下载 58

import socket
phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
phone.connect(("127.0.0.1", 8080))

while True:
    msg = input(">>").strip()
    if not msg:continue
    phone.send(msg.encode("utf-8"))
    server_data = phone.recv(1024)
    print("server back:", server_data.decode("utf-8"))

phone.close()

星彩网app下载 59

 

5.3 加上链接循环

5.3.1 服务端

星彩网app下载 60

import socket

phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
phone.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
phone.bind(("127.0.0.1", 8080))
phone.listen(5)
print("server start...")

while True: # 链接循环
    conn,client_addr = phone.accept()
    while True: # 通讯循环
        try:
            client_data = conn.recv(1024)
            if not client_data:break # 针对linux系统
            conn.send(client_data.upper())
        except Exception: # 针对windows
            break
    conn.close()

phone.close()

星彩网app下载 61

 

5.3.2 客户端

星彩网app下载 62

import socket
phone=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
phone.connect(('127.0.0.1',8080))

while True:
    msg=input('>>: ').strip()
    if not msg:continue
    phone.send(msg.encode('utf-8'))
    server_data = phone.recv(1024)
    print(server_data.decode('utf-8'))

phone.close()

星彩网app下载 63

 

5.4 模拟ssh远程实行命令

5.4.1 服务端

星彩网app下载 64

import socket
import subprocess

phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
phone.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
phone.bind(("127.0.0.1", 8080))
phone.listen(5)
print("server start...")

while True: # 链接循环
    conn,client_addr = phone.accept()
    while True: # 通讯循环
        try:
            cmd = conn.recv(1024)
            if not cmd:break # 针对linux系统

            # 执行命令,拿到结果
            res = subprocess.Popen(cmd.decode("utf-8"),
                                   shell = True,
                                   stdout = subprocess.PIPE,
                                   stderr = subprocess.PIPE)
            stdout = res.stdout.read()
            stderr = res.stderr.read()
            conn.send(stdout stderr)
        except Exception: # 针对windows
            break
    conn.close()

phone.close()

星彩网app下载 65

 

5.4.2 客户端

星彩网app下载 66

import socket
phone=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
phone.connect(('127.0.0.1',8080))

while True:
    cmd = input('>>').strip()
    if not cmd:continue
    # 发命令
    phone.send(cmd.encode('utf-8'))

    # 收命令的执行结果
    cmd_res = phone.recv(1024)

    # 打印结果
    print(cmd_res.decode('gbk'))

phone.close()

星彩网app下载 67

 

5.5 粘包现象

  Tcp现身粘包现象,udp不会冒出粘包;首假若tcp基于流式的,像水流同样,未有起头,未有最后,接踵而至 蜂拥而至,会发出粘包;udp,是数据报的,不会产出粘包。

5.5.1 服务端

星彩网app下载 68

from socket import *
s = socket(AF_INET, SOCK_STREAM)
s.bind(("127.0.0.1", 8080))
s.listen(5)

conn,addr = s.accept()

# 收发消息
data1 = conn.recv(1024)
print("data1:", data1)

data2 = conn.recv(1024)
print("data2:", data2)

conn.close()
s.close()

星彩网app下载 69

 

5.5.2 客户端

星彩网app下载 70

from socket import *
c = socket(AF_INET, SOCK_STREAM)
c.connect(("127.0.0.1", 8080))

c.send("hello".encode("utf-8"))
c.send("world".encode("utf-8"))
c.close()

星彩网app下载 71

 

5.6 ssh远程实行命令 定制报头

5.6.1 服务端

星彩网app下载 72

import socket
import struct
import subprocess
phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
phone.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
phone.bind(("127.0.0.1", 8080))
phone.listen(5)
print("server start...")
while True: # 链接循环
    conn,client_addr = phone.accept()
    print(conn, client_addr)

    while True: # 通讯循环
        try:
            cmd = conn.recv(1024)
            if not cmd:break

            # 执行命令,拿到结果
            res = subprocess.Popen(cmd.decode("utf-8"),
                                   shell=True,
                                   stdout=subprocess.PIPE,
                                   stderr=subprocess.PIPE)
            stdout = res.stdout.read()
            stderr = res.stderr.read()

            # 制作报头
            header = struct.pack("i", len(stdout) len(stderr))

            # 先发报头(固定长度)
            conn.send(header)
            # 再发真实数据
            conn.send(stdout)
            conn.send(stderr)
        except Exception: # 针对windows
            break
    conn.close()

phone.close()

星彩网app下载 73

 

5.6.2 客户端

星彩网app下载 74

import socket
import struct

phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
phone.connect(("127.0.0.1", 8080))

while True:
    cmd = input(">>").strip()
    if not cmd:continue
    # 发命令
    phone.send(cmd.encode("utf-8"))

    # 先收报头
    header = phone.recv(4)
    total_size = struct.unpack("i", header)[0]

    # 再收命令的执行结果
    recv_size = 0
    data = b""
    while recv_size < total_size:
        recv_data = phone.recv(1024)
        recv_size  = len(recv_data)
        data  = recv_data

    # 打印结果
    print(data.decode("gbk"))

phone.close()

星彩网app下载 75

 

5.7 定制报头的不利方法

5.7.1 服务端

星彩网app下载 76

import socket
import struct
import subprocess
import json
phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
phone.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
phone.bind(("127.0.0.1", 8080))
phone.listen(5)
print("server start...")
while True: # 链接循环
    conn,client_addr = phone.accept()
    print(conn, client_addr)

    while True: # 通讯循环
        try:
            cmd = conn.recv(1024)
            if not cmd:break

            # 执行命令,拿到结果
            res = subprocess.Popen(cmd.decode("utf-8"),
                                   shell=True,
                                   stdout=subprocess.PIPE,
                                   stderr=subprocess.PIPE)
            stdout = res.stdout.read()
            stderr = res.stderr.read()

            # 制作报头
            header_dic = {"total_size":len(stdout) len(stderr), "md5":None}
            header_json = json.dumps(header_dic)
            header_bytes = header_json.encode("utf-8")

            # 1.先发报头的长度(固定4个bytes)
            conn.send(struct.pack("i", len(header_bytes)))

            # 2.再发报头
            conn.send(header_bytes)

            # 3.最后发真实数据
            conn.send(stdout)
            conn.send(stderr)
        except Exception: # 针对windows
            break
    conn.close()

phone.close()

星彩网app下载 77

 

5.7.2 客户端

星彩网app下载 78

import socket
import struct
import json

phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
phone.connect(("127.0.0.1", 8080))

while True:
    cmd = input(">>").strip()
    if not cmd:continue
    # 发命令
    phone.send(cmd.encode("utf-8"))

    # 先收报头的长度
    struct_res = phone.recv(4)
    header_size = struct.unpack("i", struct_res)[0]

    # 再收报头
    header_bytes = phone.recv(header_size)
    print(header_bytes)
    head_json = header_bytes.decode("utf-8")
    head_dic = json.loads(head_json)

    total_size = head_dic["total_size"]

    # 再收命令的执行结果
    recv_size = 0
    data = b""
    while recv_size < total_size:
        recv_data = phone.recv(1024)
        recv_size  = len(recv_data)
        data  = recv_data

    # 打印结果
    print(data.decode("gbk"))

phone.close()

星彩网app下载 79

 

5.8 服务端达成产出

5.8.1 服务端

星彩网app下载 80

import socketserver

class MyTcphandler(socketserver.BaseRequestHandler):
    def handle(self):
        while True: # 通信循环
            print(self.request)
            data = self.request.recv(1024)
            self.request.send(data.upper())

if __name__ == '__main__':
    # 取代链接循环
    server = socketserver.ThreadingTCPServer(("127.0.0.1",8080), MyTcphandler)
    server.serve_forever()

星彩网app下载 81

 

5.8.2 客户端

星彩网app下载 82

import socket
phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
phone.connect(("127.0.0.1", 8080))

while True:
    msg = input(">>").strip()
    if not msg:continue
    phone.send(msg.encode("utf-8"))
    server_data = phone.recv(1024)
    print(server_data.decode("utf-8"))
phone.close()

星彩网app下载 83

 

本文由星彩网app下载发布于计算机编程,转载请注明出处:面向对象,多态与多态性

TAG标签: 星彩网app下载
Ctrl+D 将本页面保存为书签,全面了解最新资讯,方便快捷。