第八篇:python基础_8 面向对象与网络编程

时间:2021-11-11 17:23:04

本篇内容

  1. 接口与归一化设计
  2. 多态与多态性
  3. 封装
  4. 面向对象高级
  5. 异常处理
  6. 网络编程

 

一、 接口与归一化设计

1.定义

(1)归一化让使用者无需关心对象的类是什么,只需要知道这些对象都具备某些功能就可以了,这极大地降低了使用者的使用难度。

(2)归一化使得高层的外部使用者可以不加区分的处理所有接口兼容的对象集合。

2.模拟接口

#!/usr/bin/env pyhon
#encoding: utf-8
#auth: yanglei

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 du(self):
print('硬盘数据的读取方法')

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

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

def xie(self):
print('进程数据的写方法')

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

t.read()
s.read()
p.read()

 

二、多态与多态性

1.定义

多态:同一种事物的多种形态

多态性:可以在不考虑实例类型的前提下使用实例

2.应用

#!/usr/bin/env pyhon
#encoding: utf-8
#auth: yanglei

class Animal: #同一类事物:动物
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')

class Cat(Animal):
def talk(self):
print('say miaomiao')


class Bird:
def talk(self):
print('jijiji')

#多态性:可以在不考虑实例类型的前提下使用实例
p1=People()
d=Dog()
p2=Pig()
c=Cat()
b=Bird()

# p1.talk()
# d.talk()
# p2.talk()
# c.talk()
# b.talk()

def Talk(animal):
animal.talk() #p1.talk()

Talk(p1)
Talk(d)
Talk(p2)
Talk(c)
Talk(b)

 3.多态性的好处

#!/usr/bin/env pyhon
#encoding: utf-8
#auth: yanglei

#list,str,tuple
l=list([1,2,3])
t=tuple((1,2))
s=str('hello')

l.__len__()
t.__len__()
s.__len__()

def my_len(obj):
return obj.__len__()

print(my_len(l))
print(my_len(t))
print(my_len(s))

 

三、封装

1.定义

(1)封装数据属性:将属性隐藏起来,然后对外提供访问属性的接口,关键是我们在接口内定制一些控制逻辑从而严格控制使用对数据属性的使用。

(2)封装函数属性:为了隔离复杂度。

2.应用

(1)

#!/usr/bin/env pyhon
#encoding: utf-8
#auth: yanglei

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("yanglei",18)
p.tell_info()

p.set_info("Yanglei","19")
p.set_info("Yanglei",19)
p.tell_info()

(2)

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

#!/usr/bin/env pyhon
# encoding: utf-8
# auth: yanglei

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

 3.__str__

#!/usr/bin/env pyhon
# encoding: utf-8
# auth: yanglei

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)

p1=People('egon',18,'male')
p2=People('alex',38,'male')


print(p1)
print(p2)

 

四、面向对象高级

1.hasattr

#!/usr/bin/env pyhon
# encoding: utf-8
# auth: yanglei

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('yanglei')
print(f.__dict__)

print(f.name)

print(f.__dict__['name'])

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

 2.setattr

#!/usr/bin/env pyhon
# encoding: utf-8
# auth: yanglei

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

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

 3.getattr

#!/usr/bin/env pyhon
# encoding: utf-8
# auth: yanglei

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

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

 4.delattr

#!/usr/bin/env pyhon
# encoding: utf-8
# auth: yanglei

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

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

 5.应用

#!/usr/bin/env pyhon
# encoding: utf-8
# auth: yanglei

class Ftpserver:
def __init__(self,host,port):
self.host=host
self.port=port

def run(self):
while True:
cmd=input('>>: ').strip()
if not cmd:continue
if hasattr(self,cmd):
func=getattr(self,cmd)
func()
def get(self):
print('get func')

def put(self):
print('put func')

f=Ftpserver('192.168.1.2',21)
f.run()

 

五、异常处理

1.定义

异常分为两种:

(1)语法错误

(2)逻辑错误

什么时候用try ...except?
错误一定会发生,但是无法预知错误发生条件

2.应用

(1)

#!/usr/bin/env pyhon
# encoding: utf-8
# auth: yanglei

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('无论有无错误,都会执行')

 (2)

#!/usr/bin/env pyhon
# encoding: utf-8
# auth: yanglei

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

raise YangleiException('yanglei 的异常')

 

六、网络编程

1.套接字

服务端:

#!/usr/bin/env pyhon
# encoding: utf-8
# auth: yanglei

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

 客户端:

#!/usr/bin/env pyhon
# encoding: utf-8
# auth: yanglei

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

 2.通讯循环

服务端:

#!/usr/bin/env pyhon
# encoding: utf-8
# auth: yanglei

import socket
phone=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
phone.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1) #就是它,在bind前加
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('has rev')
conn.send(client_data.upper())

conn.close()

phone.close()

 客户端:

#!/usr/bin/env pyhon
# encoding: utf-8
# auth: yanglei

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'))
# print('====>has send')
server_data=phone.recv(1024)
# print('====>has recv')
print(server_data.decode('utf-8'))

phone.close()

 3.链接循环

服务端:

#!/usr/bin/env pyhon
# encoding: utf-8
# auth: yanglei

import socket
phone=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
phone.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1) #就是它,在bind前加
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:
client_data=conn.recv(1024)
if not client_data:break #针对linux系统
# print('has rev')
conn.send(client_data.upper())
except Exception: #针对windwos
break
conn.close()

phone.close()

 客户端:

#!/usr/bin/env pyhon
# encoding: utf-8
# auth: yanglei

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'))
# print('====>has send')
server_data=phone.recv(1024)
# print('====>has recv')
print(server_data.decode('utf-8'))

phone.close()

 4.解决粘包现象

服务端:

#!/usr/bin/env pyhon
# encoding: utf-8
# auth: yanglei

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) #就是它,在bind前加
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: #针对windwos
break
conn.close()

phone.close()

 客户端:

#!/usr/bin/env pyhon
# encoding: utf-8
# auth: yanglei

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

 5.实现并发

服务端:

#!/usr/bin/env pyhon
# encoding: utf-8
# auth: yanglei

import socketserver
class MyTcphandler(socketserver.BaseRequestHandler):
def handle(self):
while True: #通信循环
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()

 客户端:

#!/usr/bin/env pyhon
# encoding: utf-8
# auth: yanglei

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