1. 程式人生 > >python--面向對象與模塊補充,反射

python--面向對象與模塊補充,反射

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--面向對象與模塊補充,反射