Python面向?qū)ο缶幊袒A(chǔ)解析(二)
Python最近挺火呀,比鹿晗薛之謙還要火,當(dāng)然是在程序員之間。下面我們看看有關(guān)Python的相關(guān)內(nèi)容。
上一篇文章我們已經(jīng)介紹了部分Python面向?qū)ο缶幊袒A(chǔ)的知識(shí),大家可以參閱:Python面向?qū)ο缶幊袒A(chǔ)解析(一),接下來,我們看看另一篇。
封裝
1.為什么要封裝?
封裝就是要把數(shù)據(jù)屬性和方法的具體實(shí)現(xiàn)細(xì)節(jié)隱藏起來,只提供一個(gè)接口。封裝可以不用關(guān)心對(duì)象是如何構(gòu)建的,其實(shí)在面向?qū)ο笾?,封裝其實(shí)是最考驗(yàn)水平的
2.封裝包括數(shù)據(jù)的封裝和函數(shù)的封裝,數(shù)據(jù)的封裝是為了保護(hù)隱私,函數(shù)的封裝是為了隔離復(fù)雜度
3.數(shù)據(jù)的封裝就是在屬性前面加一個(gè)__
class People:
def __init__(self,name,age,salary):
self.name=name
self.age=age
self.__salary=salary
p=People('zhang',19,100000)
print(p.name)#zhang
print(p.age)#19
print(p.__salary)#AttributeError: 'People' object has no attribute '__salary'
咦,報(bào)錯(cuò)了,讓我們打開對(duì)象的名稱空間,看看發(fā)生了什么
print(p.__dict__)#{'name': 'zhang', 'age': 19, '_People__salary': 100000}
哦,原來python把__salary變形成了_People__salary,再來一遍
print(p._People__salary)#100000
所以,Python中并沒有絕對(duì)的隱藏,只要你知道了上面這個(gè),就無所謂隱藏了
這些變形操作,只在類的定義階段或者對(duì)象定義(實(shí)例化階段)階段發(fā)生
雖然在外部無法直接訪問加了__的屬性,但是在類內(nèi)部可以訪問到,可以這么理解,在定義階段,只要遇到__開頭的,Python解釋器自動(dòng)識(shí)別為_類名__屬性,所以在類內(nèi)部是可以訪問到的,這樣的話,我們就可以搞一點(diǎn)小事情了
先來看這個(gè)
class A:
def foo(self):
print('from A foo')
self.bar()
def bar(self):
print('from A bar')
class B(A):
def bar(self):
print('from B bar')
b=B()
b.foo() #from A foo
#from B bar 別想多了,調(diào)用函數(shù)時(shí)別看定義位置,要看調(diào)用位置
如果就是想調(diào)用父類的bar()函數(shù)呢?該怎么做
class A:
def foo(self):
print('from A foo')
self.__bar()
def __bar(self):
print('from A bar')
class B(A):
def __bar(self):
print('from B bar')
b=B()
b.foo() #from A foo
#from A bar 有沒有感受到編程的美妙
4.封裝的應(yīng)用
1)不讓外界看到我們的數(shù)據(jù)屬性是怎么定義的,只能通過我們提供的接口,看到我們?cè)试S外界看到的內(nèi)容
class People:
def __init__(self,name,age,height,weight,hobby):
self.__name=name
self.__age=age
self.__height=height
self.__weight=weight
self._hobby=hobby
def tell_info(self):
print('''
name:%s
age:%s
height:%s
weeight:%s
'''%(self.__name,self.__age,
self.__height,self.__weight))
p=People('zhang',18,1.90,75,'read')
p.tell_info()
2)更常用的場(chǎng)景是,我們可以限制數(shù)據(jù)的類型,添加自己的邏輯以后再封裝好給用戶
def tell_name(self):
print(self.__name)
#修改名字
def set_name(self,new):
if not isinstance(new,str):
raise TypeError('名字必須是字符串類型')
self.__name=new
5.看我們上面的操作,用戶查看名字的時(shí)候還得p.tell_name(),本來是個(gè)數(shù)據(jù)屬性,卻被我們搞得變成了一個(gè)函數(shù),怎么偽裝一下呢,就可以用到property這個(gè)裝飾器了
class People:
def __init__(self,name,age,height,weight,hobby):
self.__name=name
self.__age=age
self.__height=height
self.__weight=weight
self._hobby=hobby
@property
def name(self):
return self.__name
p=People('zhang',18,1.90,75,'read')
print(p.name)#zhang
數(shù)據(jù)屬性還應(yīng)該有修改,刪除操作
@property
def name(self):
return self.__name
#name已經(jīng)被property修飾過,就有setter和deleter
@name.setter
def name(self,new):
if not isinstance(new,str):
raise TypeError('名字必須是字符串類型')
self.__name=new
@name.deleter
def name(self):
del self.__name
p = People('zhang', 18, 1.90, 75, 'read')
print(p.name)#zhang
p.name='can' #修改
print(p.name)#can
del p.name #刪除
print(p.name)#AttributeError: 'People' object has no attribute '_People__name'
1.多態(tài)
多態(tài)的概念雖然現(xiàn)在才說,但是我們一直在用。多態(tài)就是多種形態(tài)的意思,動(dòng)物都貓,狗,豬等等,這些都是動(dòng)物的多種形態(tài)。
反映在Python中,多態(tài)就意味著就算不知道變量所引用的對(duì)象類型是什么,也能對(duì)它進(jìn)行操作。比如序列類型有計(jì)算長(zhǎng)度的方法len(),那我們拿到一個(gè)序列類型x,我們不需要知道x是什么類型,只需要知道它是序列類型,那我們就可以用len(x)的方法計(jì)算x的長(zhǎng)度。這就是多態(tài)性,Python本身就是多態(tài)的
當(dāng)然我們學(xué)過一個(gè)內(nèi)置函數(shù)isinstance(),可以用它來判斷數(shù)據(jù)類型,但是這可不符合多態(tài)優(yōu)美的特性
2.綁定方法與非綁定方法
類里面定義的函數(shù)有兩種,綁定方法和非綁定方法
1)綁定方法
綁定方法又分為綁定給類的方法和綁定給對(duì)象用的方法。
凡是定義在類中,且沒有被任何裝飾器修飾的方法,都是綁定給對(duì)象用的方法。
特點(diǎn)是obj.func()會(huì)自動(dòng)把obj當(dāng)作第一個(gè)參數(shù)傳入,因?yàn)閒unc的邏輯就是要處理obj
在類中定義的被classmethod裝飾器修飾的方法,就是綁定給類的方法
特點(diǎn)是cls.func()會(huì)自動(dòng)把類cls當(dāng)作第一個(gè)參數(shù)傳入,因?yàn)閒unc的邏輯是處理cls,就算是對(duì)象調(diào)用這個(gè)函數(shù),也是把類當(dāng)成第一個(gè)參數(shù)傳入
class People:
def __init__(self,name):
self.name=name
def bar(self):
print('----->',self.name)
@classmethod
def func(cls):
print(cls)
p1=People('zhang')
p1.func() #<class '__main__.People'>
People.func()#<class '__main__.People'>
2)非綁定方法
還有一種方法是既不綁定給類,也不綁定給對(duì)象的,叫做非綁定方法
用staticmethod裝飾器裝飾
#文件名:pickle_test
import hashlib
import time
import pickle
import os
student_path=r'C:\Users\Administrator\PycharmProjects\test\student'
class People:
def __init__(self,name,sex,user_id):
self.name=name
self.sex=sex
self.user_id=user_id
self.id = self.create_id()
def tell_info(self):
print('''
--------%s info--------
id:%s
name:%s
sex:%s
user_id:%s
''' %(self.name,self.id,self.name,self.sex,self.user_id))
def create_id(self):
m=hashlib.md5()
m.update(self.name.encode('utf-8'))
m.update(self.sex.encode('utf-8'))
m.update(str(self.user_id).encode('utf-8'))
return m.hexdigest()
def save(self):
with open(self.id,'wb') as f:
pickle.dump(self,f)
@staticmethod #非綁定方法,就是一個(gè)函數(shù),就是一個(gè)工具而已,不需要類,也不需對(duì)象
def get_all():
res = os.listdir(student_path)
for item in res:
file_path=r'%s\%s' %(student_path,item)
with open(file_path,'rb') as f:
obj=pickle.load(f)
obj.tell_info()
#反序列化.py
from pickle_test import People
p=People('zhang','male',123123123)
p.get_all()
3.軟件開發(fā)規(guī)范
在真正的軟件開發(fā)過程中,并不是把所有代碼寫在一個(gè)文件中的,可以想象一下,一個(gè)小程序大概有10000行代碼,都寫在一個(gè)文件中的話,你還干這行嗎?
正確的方式應(yīng)該是把程序拆成一個(gè)一個(gè)模塊。比如常用的bin目錄放可執(zhí)行文件,conf目錄放配置文件
db目錄放數(shù)據(jù),log目錄放日志文件,lib目錄放庫(kù),src目錄放一些重要的代碼,比如重要的邏輯,類的定義等
總結(jié)
以上就是本文關(guān)于Python面向?qū)ο缶幊袒A(chǔ)解析的全部?jī)?nèi)容,希望對(duì)大家有所幫助。感興趣的朋友可以繼續(xù)參閱本站:Python探索之ModelForm代碼詳解、python中requests爬去網(wǎng)頁(yè)內(nèi)容出現(xiàn)亂碼問題解決方法介紹等,如有不足之處,歡迎留言指出。感謝朋友們對(duì)本站的支持!
相關(guān)文章
Python3 tkinter 實(shí)現(xiàn)文件讀取及保存功能
tkinter是一個(gè)跨平臺(tái)的GUI庫(kù),開發(fā)的程序可以在win,linux或者mac下運(yùn)行,tkinter是python自帶的GUI庫(kù),是對(duì)圖形庫(kù)TK的封裝。本文通過實(shí)例代碼給大家介紹Python3 tkinter 實(shí)現(xiàn)文件讀取及保存功能,感興趣的朋友跟隨小編一起看看吧2019-09-09
keras獲得某一層或者某層權(quán)重的輸出實(shí)例
今天小編就為大家分享一篇keras獲得某一層或者某層權(quán)重的輸出實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2020-01-01
python3+PyQt5 自定義窗口部件--使用窗口部件樣式表的方法
今天小編就為大家分享一篇python3+PyQt5 自定義窗口部件--使用窗口部件樣式表的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2019-06-06
基于Python實(shí)現(xiàn)24點(diǎn)游戲的示例代碼
這篇文章主要為大家詳細(xì)介紹了如何利用Python實(shí)現(xiàn)24點(diǎn)游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-12-12
Python簡(jiǎn)單進(jìn)程鎖代碼實(shí)例
這篇文章主要介紹了Python簡(jiǎn)單進(jìn)程鎖代碼實(shí)例,本文講解了線程和進(jìn)程的相關(guān)知識(shí),然后給出了Python的實(shí)現(xiàn)代碼,需要的朋友可以參考下2015-04-04

