面向?qū)ο蠛瘮?shù)
封裝:
class Role(object):
n='123'#類參數(shù):大家都有的屬性,節(jié)省內(nèi)存
def __init__(self, name, role, weapon, life_value=100, money=15000):#構(gòu)造函數(shù)
self.name = name#實(shí)例參數(shù),(靜態(tài)屬性)
self.role = role
self.weapon = weapon
self.__life_value = life_value#私有屬性:類外面不可調(diào)用
self.money = money
def __del__(self):#析構(gòu)函數(shù):在實(shí)例釋放、銷毀的時(shí)候自動(dòng)執(zhí)行的,通常用于一些收尾工作,如關(guān)閉一些數(shù)據(jù)庫(kù)連接、關(guān)閉打開的臨時(shí)文件等
print('%s 徹底死了!'%self.name)
def shot(self):#類方法 功能(動(dòng)態(tài)屬性)
print("shooting...")
def got_shot(self):
print("ah...,I got shot...")
def __buy_gun(self, gun_name):#私有方法:外面不可調(diào)用
print("just bought %s" % gun_name)
r1 = Role('Alex', 'police', 'AK47') #生成一個(gè)角色
r1.n='haha'
print('r1:',r1.n)
r2 = Role('Jack', 'terrorist', 'B22') #生成一個(gè)角色
print('r2:',r2.n)
Role.n='abc'
print('類參數(shù)改后:r1:%s;r2:%s'%(r1.n,r2.n))
繼承:
#class Peple(object):#新式類
class Peple:#經(jīng)典類
def __init__(self,name):
self.name=name
self.friend=[]
def sleep(self):
print('%s sleep...'%self.name)
def eat(self):
print('%s eat...'%self.name)
class Relation(object):
def make_friends(self,obj):
print('%s make friends with %s'%(self.name,obj.name))
self.friend.append(obj)#傳的是對(duì)象內(nèi)存,而不是值
class Man(Peple,Relation):#多繼承
def __init__(self,name,age):#添加實(shí)例參數(shù)
# Peple.__init__(self,name)#經(jīng)典類
super(Man,self).__init__(name)#新式類
self.age=age
print('%s age:%s'%(self.name,self.age))
def work(self):
print('%s work...'%self.name)
def make_monkey(self):#調(diào)用父類函數(shù)
Peple.sleep(self)
print('%s make_money...'%self.name)
class Woman(Peple):#繼承Peple
def shopping(self):
print('%s shopping...'%self.name)
m=Man('haha',3)
m.eat()
m.make_monkey()
w=Woman('enen')
w.shopping()
m.make_friends(w)
w.name='yoyo'
print(m.friend[0].name)
繼承實(shí)例(多繼承):經(jīng)典類和新式類都是統(tǒng)一按廣度優(yōu)先來(lái)繼承的
class School(object):
def __init__(self,name,addr):
self.name=name
self.addr=addr
self.student=[]
self.staff=[]
def enroll(self,stu_obj):
print('%s enroll student[%s]'%(self.name,stu_obj.name))
self.student.append(stu_obj)
def hire(self,staff_obj):
print('%s hire staff[%s]'%(self.name,staff_obj.name))
self.staff.append(staff_obj)
class SchoolMenber(object):
def __init__(self,name,age,sex):
self.name=name
self.age=age
self.sex=sex
def tell(self):
print('[%s] is telling... '%self.name)
class Teacher(SchoolMenber):
def __init__(self,name,age,sex,salary,course):
super(Teacher,self).__init__(name,age,sex)
self.salary=salary
self.course=course
def tell(self):
print('''
info of Teacher[%s]
TeacherName:%s
TeacherAge:%s
TeacherSex:%s
TeacherSalary:%s
TeacherCourse:%s
'''%(self.name,self.name,self.age,self.sex,self.salary,self.course))
def teach(self):
print('teacher [%s] teach course[%s]'%(self.name,self.course))
class Student(SchoolMenber):
def __init__(self,name,age,sex,stu_id,grade):
super(Student,self).__init__(name,age,sex)
self.stu_id=stu_id
self.grade=grade
def tell(self):
print('''
info of Student[%s]
StudentName:%s
StudentAge:%s
StudentSex:%s
StudentStu_id:%s
StudentGrade:%s
''' % (self.name, self.name, self.age, self.sex, self.stu_id, self.grade))
def pay_tuition(self,amount):
print('student[%s] has pay_tuition $[%s]'%(self.name,amount))
school=School('川化','青白江')
t1=Teacher('YoYo',35,'F',5000,'Python')
t2=Teacher('QQ',40,'M',8000,'go')
s1=Student('haha',15,'F',25,'Python')
s2=Student('enen',19,'M',31,'go')
t1.tell()
#輸出:
'''
info of Teacher[YoYo]
TeacherName:YoYo
TeacherAge:35
TeacherSex:F
TeacherSalary:5000
TeacherCourse:Python
'''
s1.tell()
#輸出:
'''
info of Student[haha]
StudentName:haha
StudentAge:15
StudentSex:F
StudentStu_id:25
StudentGrade:Python
'''
school.enroll(s1)
#輸出:川化 enroll student[haha]
school.enroll(s2)
#輸出:川化 enroll student[enen]
school.hire(t1)
#輸出:川化 hire staff[YoYo]
school.hire(t2)
#輸出:川化 hire staff[QQ]
school.student[0].pay_tuition(500)
#輸出:student[haha] has pay_tuition $[500]
print(school.staff)
#輸出:[<__main__.Teacher object at 0x00000000027FAE80>, <__main__.Teacher object at 0x00000000027FAEB8>]
for staff in school.staff:
staff.teach()
#輸出:
'''
teacher [YoYo] teach course[Python]
teacher [QQ] teach course[go]
'''
多態(tài):實(shí)現(xiàn)接口重用
class Animal(object):
def __init__(self,name):
self.name=name
@staticmethod
def animal_talk(obj):
obj.talk()
class Dog(Animal):
def talk(self):
print('wang wang')
class Cat(Animal):
def talk(self):
print('miao miao')
d=Dog('haha')
d.talk()
#輸出:wang wang
c=Cat('enen')
c.talk()
#輸出:miao miao
Animal.animal_talk(d)
#輸出:wang wang
Animal.animal_talk(c)
#輸出:miao miao
靜態(tài)方法、類方法、屬性方法
class Person(object):
n='enen'
def __init__(self,name):
self.name=name
@staticmethod
def eat(food):
#靜態(tài)方法已經(jīng)和類沒有關(guān)系了
#只是名義上歸類管理,實(shí)際上在靜態(tài)方法里訪問不了類或?qū)嵗械娜魏螌傩? print('eat %s'%food)
@property#屬性方法就是把一個(gè)方法變成一個(gè)靜態(tài)屬性
def sleep(self):
print('%s is sleeping...'%self.name)
@sleep.setter
def sleep(self,new_name):
print('%s change to %s'%(self.name,new_name))
self.name=new_name
@sleep.deleter
def sleep(self):
print('delete sleep...')
@classmethod
def talk(self,talking):
#類方法只能訪問類變量,不能訪問實(shí)例變量
print('%s talk "%s"'%(self.n,talking))
person=Person('haha')
person.eat('包子')
person.talk('hhhhhhh')
person.sleep='yoyo'
person.sleep
del person.sleep#觸發(fā) @sleep.deleter
#輸出:
'''eat 包子
enen talk "hhhhhhh"
haha change to yoyo
yoyo is sleeping...
delete sleep...
yoyo is sleeping...
'''
類的特殊成員方法
__doc__:表示類的描述信息
class Fo(object):
'''描述類信息'''
def func(self):
pass
print(Fo.__doc__)
#輸出:描述類信息
__module__ 和 __class__
__module__表示當(dāng)前操作的對(duì)象在那個(gè)模塊
__class__表示當(dāng)前操作的對(duì)象的類是什么
class C:
def __init__(self):
self.name = 'wupeiqi'
from lib.aa import C
obj = C()
print obj.__module__ # 輸出 lib.aa,即:輸出模塊
print obj.__class__ # 輸出 lib.aa.C,即:輸出類
__call__對(duì)象后面加括號(hào),觸發(fā)執(zhí)行
class Foo:
def __init__(self):
pass
def __call__(self, *args, **kwargs):
print ('running...',args,kwargs)
obj = Foo() # 執(zhí)行 __init__
obj() # 執(zhí)行 __call__
__dict__查看類或?qū)ο笾械乃谐蓡T
__str__如果一個(gè)類中定義了__str__方法,那么在打印對(duì)象時(shí),默認(rèn)輸出該方法的返回值
class Fo(object):
n='enen'
def __init__(self,name):
self.name=name
def func(self):
pass
def __str__(self):
return 'obj:%s'%self.name
print(Fo.__dict__)#打印類里的所有屬性,不包括實(shí)例對(duì)象
#輸出:{'__module__': '__main__', 'n': 'enen', '__init__': <function Fo.__init__ at 0x00000000021EA950>, 'func': <function Fo.func at 0x00000000021EA8C8>, '__call__': <function Fo.__call__ at 0x00000000021EAC80>, '__dict__': <attribute '__dict__' of 'Fo' objects>, '__weakref__': <attribute '__weakref__' of 'Fo' objects>, '__doc__': None}
print(Fo('haha').__dict__)#打印所有實(shí)例對(duì)象,不包括類屬性
#輸出:{'name': 'haha'}
print(Fo('haha'))
#輸出:obj:haha
__getitem__、__setitem__、__delitem__
用于索引操作,如字典。以上分別表示獲取、設(shè)置、刪除數(shù)據(jù)
class Foo(object):
def __getitem__(self, key):
print('__getitem__',key)
def __setitem__(self, key, value):
print('__setitem__',key,value)
def __delitem__(self, key):
print('__delitem__',key)
obj = Foo()
result = obj['k1'] # 自動(dòng)觸發(fā)執(zhí)行 __getitem__
obj['k2'] = 'alex' # 自動(dòng)觸發(fā)執(zhí)行 __setitem__
del obj['k1']
注:類 是由 type 類實(shí)例化產(chǎn)生
def func(self):
print('hello[%s]this is func!'%self.name)
def __init__(self,name):
self.name=name
f=type('Foo',(object,),{'welcome':func,'__init__':__init__})
h=f('haha')
h.welcome()
反射
通過字符串映射或修改程序運(yùn)行時(shí)的狀態(tài)、屬性、方法, 有以下4個(gè)方法
def talk(self):
print('%s is talking...'%self.name)
class Foo(object):
def __init__(self,name):
self.name=name
def eat(self,food):
print('%s is eating %s'%(self.name,food))
f=Foo('haha')
a='eat'
b='talking'
c='name'
'''
hasattr(obj,name_str),判斷一個(gè)對(duì)象obj里是否有對(duì)應(yīng)的name_str字符串的方法
'''
print(hasattr(f,a))
#輸出:True
print(hasattr(f,b))
#輸出:False
print(hasattr(f,c))
#輸出:True
'''
getattr(obj,name_str),根據(jù)字符串去獲取obj對(duì)象里的對(duì)應(yīng)的方法的內(nèi)存地址
'''
print(getattr(f,a))
#輸出:<bound method Foo.eat of <__main__.Foo object at 0x0000000001E08F98>>
getattr(f,a)('包子')
#輸出:haha is eating 包子
print(getattr(f,c))
#輸出:haha
'''
setattr(obj,name_str,z),在obj對(duì)象里根據(jù)字符串創(chuàng)建新的方法,z代表已有的方法或?qū)嵗齾?shù)
'''
setattr(f,b,talk)
f.talking(f)
#輸出:haha is talking...
setattr(f,b,22)
print(f.talking)
#輸出:22
'''
delattr(obj,name_str),刪除obj對(duì)象里對(duì)應(yīng)的字符串方法或?qū)嵗齾?shù)
'''
delattr(f,a)
f.eat('饅頭')
#輸出:報(bào)錯(cuò):AttributeError: eat
delattr(f,c)
f.name
#輸出:報(bào)錯(cuò):AttributeError: 'Foo' object has no attribute 'name'
動(dòng)態(tài)導(dǎo)入模塊

image.png
import importlib
c=importlib.import_module('day6.cs')
a=c.Role('haha','police','ak')
異常
異常處理
正常出錯(cuò):
a={'1':'a'}
a[2]
#報(bào)錯(cuò):KeyError: 2
b=[1,2,3]
b[3]
#報(bào)錯(cuò):IndexError: list index out of range
錯(cuò)誤處理:
try:
a[2]
except KeyError as e:
print (e)
#輸出:2
try:
b[3]
except IndexError as e:
print (e)
#輸出:list index out of range
嚴(yán)密處理:
try:
a[2]
b[3]
except (KeyError,IndexError) as e:
print (e)
except Exception as mg:
print ('其他錯(cuò)誤')
else:print ('一切正常')
finally:print ('不管有無(wú)錯(cuò)誤都會(huì)執(zhí)行')
#輸出:
'''
2
不管有無(wú)錯(cuò)誤都會(huì)執(zhí)行
'''
自定異常
class HahaError(Exception):
def __init__(self,msg):
self.massage=msg
def __str__(self):
return '錯(cuò)誤類型:Haha'
try:
raise HahaError('連接數(shù)據(jù)庫(kù)。。。')
except HahaError as msg:
print (msg)
#輸出:錯(cuò)誤類型:Haha
Socket編程
建立一個(gè)socket必須至少有2端, 一個(gè)服務(wù)端,一個(gè)客戶端, 服務(wù)端被動(dòng)等待并接收請(qǐng)求,客戶端主動(dòng)發(fā)起請(qǐng)求, 連接建立之后,雙方可以互發(fā)數(shù)據(jù)。

image.png
基本的socket實(shí)現(xiàn)
socket_server:
import socket
server=socket.socket()
server.bind(('localhost',1234))#綁定要監(jiān)聽端口
server.listen(3)#監(jiān)聽,允許多少連接等待
print('開始等待指定端口號(hào)連接口號(hào)')
while True:
con,addr=server.accept()#連接進(jìn)來(lái)。。。
#con就是客戶端連過來(lái)而在服務(wù)器為其生成的一個(gè)連接實(shí)例
print(con,addr)
print('連接進(jìn)來(lái)。。。')
while True:
data=con.recv(1024)
print('recv:',data.decode())
if not data:
print('client has closed')
break
con.send(data)
server.close()
socket_client:
import socket
client=socket.socket()#聲明socket類型,同時(shí)生成socket連接對(duì)象
client.connect(('localhost',1234))
while True:
input_data=input('>').strip()
if len(input_data)==0:continue
client.send(input_data.encode('utf-8'))
data=client.recv(1024)
print('rece:',data.decode())
client.close()
使用socket實(shí)現(xiàn)簡(jiǎn)單ssh功能
server:
import socket,os
server=socket.socket()
server.bind(('localhost',6666))
server.listen()
while True:
con,addr=server.accept()
print('已連接:',addr)
while True:
cmd_data = con.recv(1024)
print('接收指令:',cmd_data.decode())
if not cmd_data:
print('客服端以斷開')
break
cmd_res=os.popen(cmd_data.decode()).read()#運(yùn)行命令
if len(cmd_res)==0:#有可能會(huì)報(bào)錯(cuò),就造一個(gè)cmd_res數(shù)據(jù),保證通話繼續(xù)
cmd_res='執(zhí)行結(jié)果為空'
cmd_res_size=len(cmd_res)
print('cmd_res_size:',cmd_res_size)
con.send(str(cmd_res_size).encode('utf-8'))#返回執(zhí)行結(jié)果的長(zhǎng)度
print('cmd_res:',cmd_res)
# client_ack=con.recv(1024)#如果連續(xù)發(fā)送的數(shù)據(jù)發(fā)生粘包,就使用這種處理方法
# print('client_ack:',client_ack.decode())
con.send(cmd_res.encode('utf-8'))
server.close()
client:
import socket
client=socket.socket()
client.connect(('localhost',6666))
while True:
cmd_data=input('請(qǐng)輸入指令:').strip()
if len(cmd_data)==0:continue#如果輸入字符為空,則重新輸入
client.send(cmd_data.encode('utf-8'))
cmd_res_size=client.recv(1024)#接收運(yùn)行結(jié)果的長(zhǎng)度
print('cmd_res_size:',int(cmd_res_size.decode()))
# client.send('cmd_res_size已收到!'.encode('utf-8'))#防止連續(xù)接收的數(shù)據(jù)發(fā)生粘包
receive_size=0
while receive_size!=int(cmd_res_size.decode()):#存在運(yùn)行結(jié)果太長(zhǎng),一次接收不完,則分多次接收,判斷接收的長(zhǎng)度不等于總長(zhǎng)度,則繼續(xù)接收
cmd_res = client.recv(1024)
print('運(yùn)行結(jié)果如下:', cmd_res.decode())
receive_data_size=len(cmd_res.decode())
receive_size+=receive_data_size
else:print('接收完畢')
client.close()
使用socket實(shí)現(xiàn)ftp功能
server:
import socket,os,hashlib
server=socket.socket()
server.bind(('localhost',8888))
server.listen()
while True:
con,addr=server.accept()
print('已連接:',addr)
while True:
data=con.recv(1024).decode()
cmd,filename= data.split()
m=hashlib.sha256()
print('接收指令:',cmd)
if not data:
print('客服端以斷開')
break
if os.path.isfile(filename):
f=open(filename,'rb')
file_size=os.stat(filename).st_size
con.send(str(file_size).encode('utf-8'))
print('file_size:',file_size)
con.recv(1024)
for line in f:
con.send(line)
m.update(line)
con.send(m.hexdigest().encode('utf-8'))
print('sha256加密碼:',m.hexdigest())
f.close()
server.close()
client:
import socket,hashlib
client=socket.socket()
client.connect(('localhost',8888))
m=hashlib.sha256()
while True:
cmd_data=input('請(qǐng)輸入指令:').strip()
if len(cmd_data)==0:continue#如果輸入字符為空,則重新輸入
client.send(cmd_data.encode('utf-8'))
cmd,filename=cmd_data.split()
if cmd=='get':
file_size=client.recv(1024)#接收運(yùn)行結(jié)果的長(zhǎng)度
print('file_size:',int(file_size.decode()))
client.send('file_size已收到!'.encode('utf-8'))#防止連續(xù)接收的數(shù)據(jù)發(fā)生粘包
receive_size=0
f=open(filename+'new','wb')
while receive_size!=int(file_size.decode()):#存在運(yùn)行結(jié)果太長(zhǎng),一次接收不完,則分多次接收,判斷接收的長(zhǎng)度不等于總長(zhǎng)度,則繼續(xù)接收
if int(file_size.decode())-receive_size>1024:#判斷所剩文件大小是否小于1024,不小于繼續(xù)接收,小于就只接收剩余大小文件,以便最后一次接收和sha256密碼發(fā)生粘包
size=1024
else:
size=int(file_size.decode())-receive_size
print('最后一次size:',size)
cmd_line = client.recv(size)
f.write(cmd_line)
receive_data_size=len(cmd_line)
receive_size+=receive_data_size
m.update(cmd_line)
else:
print('接收完畢')
receive_m=client.recv(2014).decode()#接收服務(wù)端發(fā)送的密碼
f.close()
print('receive_m:',receive_m)
print('m:',m.hexdigest())#自己的密碼
client.close()
Socket實(shí)現(xiàn)多線程TCP網(wǎng)絡(luò)服務(wù)
server:
import socketserver
class MyTcpHandler(socketserver.BaseRequestHandler):
def handle(self):
while True:
try:
print('請(qǐng)求IP:',self.client_address[0])
self.data=self.request.recv(1024)
print('recv:',self.data.decode())
self.request.send(self.data.upper())
except ConnectionResetError as e:
print('error:',e)
break
if __name__ == '__main__':
host,addr=('localhost'),1234
server=socketserver.ThreadingTCPServer((host,addr),MyTcpHandler)
server.serve_forever()
client同基本的socket實(shí)現(xiàn)中client