標籤:python 物件導向 模組反射
在python中,私人屬性可以通過__(兩個底線定),實際上一個底線也表示私人屬性,不過還是可以訪問到
關於私人屬性、方法——Python並沒有真正的私人化支援,但可用底線得到偽私人,所以盡量避免定義以底線開頭的變數
"單底線 " 開始的成員變數叫做保護變數,意思是只有類對象(即類執行個體)和子類對象自己能訪問到這些變數,需通過類提供的介面進行訪問;不能用'from module import *'匯入,類似於php的protected受保護的,直接通過執行個體化對象和子類都可以訪問
class People(object):
_test1 = "一個底線的私人屬性"
__test = '兩個底線的私人屬性'
def __init__(self,name):
self.name = name
def run(self):
print("%s is running" %self.name)
p = People("Jack")
p.run()
print(p._test1)
" 雙底線 " 開始的是私人成員,意思是只有類對象自己能訪問,連子類對象也不能訪問到這個資料。
class People(object):
_test1 = "一個底線的私人屬性"
__test = '兩個底線的私人屬性'
def __init__(self,name):
self.name = name
def run(self):
print("%s is running" %self.name)
p = People("Jack")
p.run()
print(p._test1)
print(p.__test)
print(People.__test)
類名也是不能直接存取的:
其實這隻是表象通過__dict__查看所以屬性
print(People.__dict__)
其實python重新對雙底線的私人變數重新定義了,所以通過重新定義的名字可以直接存取即通過_類名__屬性名稱訪問
print(p._People__test)
可以直接存取
私人方法的訪問:
正常是通過類內部提供的方法訪問
私人的屬性,不能通過對象直接存取,但是可以通過方法訪問
私人的方法,不能通過對象直接存取
私人的屬性、方法,不會被子類繼承,也不能被訪問
一般情況下,私人的屬性、方法都是不對外公布的,往往用來做內部的事情,起到安全的作用
可以通過調用繼承的父類的共有方法,間接的訪問父類的私人方法、屬性
對於封裝,類本身就是一種封裝,定義私人屬性方法也屬於一種封裝,還有一種就是內部實現的邏輯,外部無法訪問,只聽提供一個介面供外調用。
反射:
python物件導向中的反射:通過字串的形式操作對象相關的屬性。python中的一切事物都是對象(都可以使用反射)
四個可以實現自省的函數
下列方法適用於類和對象(一切皆對象,類本身也是一個對象)
執行:
m()
設定屬性
#設定屬性
setattr(p,'school',"qinghua")#等於p.school='qinghua'
print(p.school)
#修改也可以
setattr(p,'name',"lucy")
print(p.name)
刪除:
setattr(p,'name',"lucy")
print(p.name)
delattr(p,"school")
delattr(p,"schools")#刪除不存在的會報錯
#print(p.school)
反射可以事先定義好介面,介面只有在被完成後才會真正執行,這實現了隨插即用,這其實是一種‘後期綁定’,意思是可以事先把主要的邏輯寫好(只定義介面),然後後期再去實現介面的功能,
匯入其他模組,利用反射尋找該模組是否存在某個方法
A檔案。im2.py
class A():
#'A先定義,但是還沒有實現具體的功能'
def __init__(self,addr):
print('定義好介面未實現')
self.addr=addr
B檔案。demo.py
from im2 import A
a = A("china")
if hasattr(a,'get'):
func_get=getattr(a,'get')
func_get()
else:
print('---->不存在此方法')
print('處理其他的邏輯')
print("im2檔案")
def test():
print("test")
def test1():
print("test1")
module_test = __import__('demo.im2')#擷取檔案名稱
print(module_test)
可以看出匯入後會執行匯入的檔案
module_test = __import__('im2')
print(module_test)
module_test.test()#直接調用,如果是檔案夾要寫上包的名字例如im2.py在demo檔案夾下,module_test.im2.test()
模組在匯入的時候如果使用了,from module import * 那麼私人方法不能被匯入
會報錯
如果改為直接調用可以運行,這說明python沒有絕對的私人機制
雙底線也一樣
python--物件導向與模組補充,反射