多态与多态性,互联网编制程序

一.
哪些是多态

面向对象学习目录

一 接口与归壹化设计

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

前些天说了面向对象3大特征的后续,今天的话多态和包装,很多别样程序员说python不帮忙多态没有多态,并不是python没有多态,而是python四处皆多态。明天的上书重点会放在封装。

 

一、多态

1、多态

多态指的是一类东西有三种模样

水有各样样子:冰 水雾 水

动物有三种模样:人,狗,猪

澳门葡京备用网址 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')

多态

文本有多样形态:文本文件,可执行文件

澳门葡京备用网址 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、多态性

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

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

向不一样的目的发送同一条音讯,不相同的靶子在收受时会发生不一样的行事(即方法)。约等于说,每一种对象足以用本身的章程去响应共同的新闻。所谓音讯,就是调用函数,差别的一举一动正是指分歧的贯彻,即举行不相同的函数。

譬如说:老师.下课铃响了(),学生.下课铃响了(),老师执行的是下班操作,学生举行的是放学操作,纵然两者音讯无异于,不过实行的效劳不一样

澳门葡京备用网址 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程序员常常依照那种表现来编写程序。例如,倘诺想编写现有对象的自定义版本,能够继续该对象也得以创立三个外观和作为像,但与它无别的涉及的崭新对象,后者日常用于保存程序组件的松耦合度。

例一:利用标准库中定义的各样‘与公事类似’的靶子,固然这个目的的行事办法像文件,但她俩未有继续内置文件对象的不二等秘书诀

例二:类别类型有四种形态:字符串,列表,元组,但她们径直未有平素的接轨关系

澳门葡京备用网址 4例子


 

二、封装

包裹:隐藏对象的习性和兑现细节,仅对外提供公共访问格局。

好处:

壹、 将扭转隔断; 

贰.、便于使用;

三.、提升复用性; 

四.、提升安全性;

包装原则:

1、 将不须求对外提供的始末都掩藏起来;

贰、 把品质都隐藏,提供公共艺术对其访问。

1、私有变量

澳门葡京备用网址 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是可以访问到的,即这种操作并不是严格意义上的限制外部访问,仅仅只是一种语法意义上的变形

多态与多态性,互联网编制程序。村办变量

特点:

一、类中定义的__x只幸好中间接选举拔,如self.__x,引用的正是变形的结果。

2、那种变形其实便是针对外部的变形,在外表是力不从心透过__x这么些名字访问到的。

3、在子类定义的__x不会覆盖在父类定义的__x,因为子类中变形成了:_子类名__x,而父类中变形成了:_父类名__x,即双下滑线开端的习性在一而再给子类时,子类是力不从心掩盖的。

注意:

那种体制也并从未真的意义上限定我们从外表直接待上访问属性,知道了类名和属性名就足以拼盛名字:_类名__质量,然后就能够访问了,如a._A__N

贰、私有方法

在几次三番中,父类假如不想让子类覆盖本人的办法,能够将艺术定义为私有的

 

澳门葡京备用网址 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、扩展性

封装在于鲜明区分内外,使得类完成者能够修改封装内的事物而不影响外部调用者的代码;而外部使用用者只知道贰个接口(函数),只要接口(函数)名、参数不变,使用者的代码永远无需变更。

澳门葡京备用网址 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属性

澳门葡京备用网址 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指数
澳门葡京备用网址 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是实施了3个函数然后计算出来的,那种天性的采纳格局服从了合并访问的尺度

。。。

(剩余今天后续立异)

 

 

 

 

 

今天说了面向对象3大特点的延续,明天来说多态和打包,很多别的程序员说python不协理多态未有…

    多态指的是相同种/类东西的不如造型

一 面向对象介绍

1.1 归1化概念:

  归一化的利益:

  壹.归一化让使用者无需关切对象的类是什么样,只供给驾驭这么些目的都富有有些职能就足以了,那庞大下落了使用者的行使难度。

  贰.归一化使得高层的外部使用者能够不加区分的拍卖全部接口包容的目的集合

 

  继承的二种用途

  ①:继承基类的章程,并且做出自个儿改变依然扩充(代码重用):实践中,继承的那种用途意义并不十分大,甚至不时是加害的。因为它使得子类与基类出现强耦合。

  贰:注脚有个别子类包容于某基类,定义四个接口类(模仿java的Interface),接口类中定义了有的接口名(正是函数名)且从未落成接口的意义,子类继承接口类,并且达成接口中的功用

澳门葡京备用网址 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()    # 运行结果:进程数据的读取方法

澳门葡京备用网址 11

 

二.怎么要用多态性

二类、实例、属性、方法详解

1.2 抽象类

  明白知识点

  与java1样,python也有抽象类的概念可是同样供给借助模块完成,抽象类是1个出奇的类,它的奇特之处在于只好被三番五次,不能够被实例化

  借助abc模块,实行模拟抽象类

澳门葡京备用网址 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()

澳门葡京备用网址 13

 

  壹扩充了程序的油滑

三面向进程与面向对象进一步相比较

1.3 多态

  面向对象的多态、多态性

  多态:指的是平等种东西的有余形态

  动物有七种模样:人、狗、猪

澳门葡京备用网址 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()

澳门葡京备用网址 15

 

  二十日增了程序的可扩大性

四 类与对象

1.4 多态性

  多态性:能够在不思念实例类型的前提下采用实例

澳门葡京备用网址 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)

澳门葡京备用网址 17

 

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

5属性查找与绑定方法

1.5 多态性的裨益

  多态性的补益:

  1.充实了程序的灵活性

  二.扩张了先后可扩张性

 

    多态性:在多态的背景下,能够在毫不思虑对象实际品种的前提下而直白动用对象

6 小结

一.陆 鸭子类型

  Python崇尚鸭子类型,即‘若是看起来像、叫声音图像而且走起路来像鸭子,那么它正是鸭子’

  python程序员日常依照那种行为来编写程序。例如,假设想编写现有对象的自定义版本,能够三番五次该对象

  也得以创建3个外观和行事像,但与它无其余涉及的全新对象,后者日常用于保存程序组件的松耦合度。

  利用标准库中定义的种种‘与公事类似’的靶子,固然这个指标的办事措施像文件,但他俩平昔不继承内置文件对象的法子

澳门葡京备用网址 18

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

    def write(self):
        pass

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

澳门葡京备用网址 19

 

    多态性的精髓:统一

7 继承与派生

2 封装

三.
怎样用多态

8 组合

2.1 隐藏

  在python中用双下划线初步的不贰秘籍将品质隐藏起来

澳门葡京备用网址 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

澳门葡京备用网址 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.贰 封装数据属性

澳门葡京备用网址 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>

澳门葡京备用网址 23

 

python 崇尚鸭子类型

10 多态

2.三 封装函数属性

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

澳门葡京备用网址 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()
# 运行结果:
#       插卡
#       用户认证
#       输入取款金额
#       打印账单
#       取款

澳门葡京备用网址 25

 

逗比每1天:

11 封装

二.四 静态属性

澳门葡京备用网址 26

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

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

澳门葡京备用网址 27

  示例:计算BMI指数

澳门葡京备用网址 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)

澳门葡京备用网址 29

 

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

12绑定方法与非绑定方法

三 面向对象高级

python程序员常常依照那种行为来编写程序。例如,假若想编写现有对象的自定义版本,能够继续该指标

一三 内置方法(上)

3.1 反射

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

澳门葡京备用网址 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__)

澳门葡京备用网址 31

 

也能够创制1个外观和作为像,但与它无其余关联的崭新对象,后者常常用于保存程序组件的松耦合度。

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

3.2 item系列

  Item系类,首要不外乎:__getitem__、__setitem__、
__delitem__,通过那多少个item,能够像操作字典一样,操作对象的属性。

澳门葡京备用网址 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__)

澳门葡京备用网址 33

 

例一:利用标准库中定义的各类‘与公事类似’的靶子,就算那几个指标的办事形式像文件,但他们未尝继承内置文件对象的法子

一伍 内置方法(下)

3.3 __str__

  通过__str__,打印对象消息

澳门葡京备用网址 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>

澳门葡京备用网址 35

 

澳门葡京备用网址 36澳门葡京备用网址 37

16 元类

三.肆 析构方法

  用法:清理一些财富,清理一些python解析器无法清理的能源,例如:清理操作系统的能源,打开文件,向操作系统一发布起调用,关闭文件句柄财富

澳门葡京备用网址 38

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

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

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

澳门葡京备用网址 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 异常

澳门葡京备用网址 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

澳门葡京备用网址 41

 

View Code

多态

  抽象类统一标准了有的相似类的貌似个性后,继承该抽象类的相继子类的具体表现方式是足以多种八种的(具体表现为:数据属性的值各不同、函数属性的函数体各不同)

  多态指的是1类东西有各个形态,比如

  动物有种种模样:人,狗,猪

 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')

 

四.一 卓殊处理

  尽管不当产生的标准可预言的,我们供给用if进行拍卖,在错误发生以前开始展览预防

  假设不当发生的原则时不得预感的,则须要用到try…except,在错误发生之后进行处理

澳门葡京备用网址 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()

澳门葡京备用网址 43

 

 

多态性

1、什么是多态动态绑定(在后续的背景下选用时,有时也叫做多态性)

  多态性是指在不考虑实例类型的情事下使用实例,多态性分为静态多态性和动态多态性

  静态多态性:如别的项目都足以用运算符+实行演算

  动态多态性:如下

 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()

就此,计算下抽象类与多态的关系:

  先由抽象类统一定义那个相似类的形似本性(包蕴数据属性和函数属性,当中规定各相似类必须定义那一个函数属性概念的函数体能够两种形象),然后再将一般的函数属性用统1的接口归一化调用(统一接口的功底是各子类都正式需求了定义那个相似函数属性),从而完结了“同一接口,三种形态”

 

二、为啥要用多态性(多态性的补益)

  其实我们从上面多态性的例证能够见到,大家并未增添哪些新的知识,也正是说python本人正是支撑多态性的,这么做的益处是何等呢?

一.日增了先后的油滑

  以不变应万变,不论对象翻云覆雨,使用者都以1样种方式去调用,如func(animal)

二.扩充了程序额可增加性

  
 通过继承animal类创制了3个新的类,使用者无需更改自身的代码,依旧用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)
'''

 

四.2 多分支非凡

澳门葡京备用网址 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)

澳门葡京备用网址 45

 

鸭子类型

逗比每天:

      
 Python崇尚鸭子类型,即‘要是看起来像、叫声像而且走起路来像鸭子,那么它正是鸭子’

      
 python程序员平时依照这种作为来编写程序。例如,倘诺想编写现有对象的自定义版本,能够接二连三该指标

      
 也得以创立3个外观和行为像,但与它无任何关系的全新对象,后者平时用于保存程序组件的松耦合度。

 

例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 万能十一分

澳门葡京备用网址 46

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

澳门葡京备用网址 47

 

4.4 基本结构

澳门葡京备用网址 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('无论有无错误,都会执行')

澳门葡京备用网址 49

 

四.五 自定义相当

澳门葡京备用网址 50

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

raise EgonException('jack 的异常')

澳门葡京备用网址 51

 

5 Socket编程

  IP + 端口,标识唯十三个软件、应用

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

伍.壹 不难套接字

5.1.1 服务端

澳门葡京备用网址 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()

澳门葡京备用网址 53

 

5.1.2 客户端

澳门葡京备用网址 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() 

澳门葡京备用网址 55

 

5.二 加上通讯循环

5.2.1 服务端

澳门葡京备用网址 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()

澳门葡京备用网址 57

 

5.2.2 客户端

澳门葡京备用网址 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()

澳门葡京备用网址 59

 

5.三 加上链接循环

5.3.1 服务端

澳门葡京备用网址 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()

澳门葡京备用网址 61

 

5.3.2 客户端

澳门葡京备用网址 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()

澳门葡京备用网址 63

 

5.四 模拟ssh远程执行命令

5.4.1 服务端

澳门葡京备用网址 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()

澳门葡京备用网址 65

 

5.4.2 客户端

澳门葡京备用网址 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()

澳门葡京备用网址 67

 

伍.伍 粘包现象

澳门葡京备用网址 ,  Tcp出现粘包现象,udp不会出现粘包;重假若tcp基于流式的,像水流一样,未有起来,未有最后,接踵而来,会发生粘包;udp,是数据报的,不会并发粘包。

5.5.1 服务端

澳门葡京备用网址 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()

澳门葡京备用网址 69

 

5.5.2 客户端

澳门葡京备用网址 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()

澳门葡京备用网址 71

 

五.陆 ssh远程执行命令+定制报头

5.6.1 服务端

澳门葡京备用网址 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()

澳门葡京备用网址 73

 

5.6.2 客户端

澳门葡京备用网址 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()

澳门葡京备用网址 75

 

伍.7 定制报头的科学方法

5.7.1 服务端

澳门葡京备用网址 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()

澳门葡京备用网址 77

 

5.7.2 客户端

澳门葡京备用网址 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()

澳门葡京备用网址 79

 

伍.捌 服务端完毕产出

5.8.1 服务端

澳门葡京备用网址 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()

澳门葡京备用网址 81

 

5.8.2 客户端

澳门葡京备用网址 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()

澳门葡京备用网址 83

 

相关文章

发表评论

电子邮件地址不会被公开。 必填项已用*标注

*
*
Website