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重新對雙下劃線的私有變量重新定義了,所以通過重新定義的名字可以直接訪問即通過_類名__屬性名訪問
可以直接訪問
私有方法的訪問:
正常是通過類內部提供的方法訪問
私有的屬性,不能通過對象直接訪問,但是可以通過方法訪問
私有的方法,不能通過對象直接訪問
私有的屬性、方法,不會被子類繼承,也不能被訪問
一般情況下,私有的屬性、方法都是不對外公布的,往往用來做內部的事情,起到安全的作用
可以通過調用繼承的父類的共有方法,間接的訪問父類的私有方法、屬性
對於封裝,類本身就是一種封裝,定義私有屬性方法也屬於一種封裝,還有一種就是內部實現的邏輯,外部無法訪問,只聽提供一個接口供外調用。
反射:
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--面向對象與模塊補充,反射