python包裝和授權

2021-07-05 01:57:15 字數 4852 閱讀 5660

首先了解什麼是包裝和授權。

我們知道,物件導向程式設計中有乙個理念就是封裝,而實際上物件導向也讓程式設計師在使用一些類(自己定義或則別人定義)物件的時候非常方便。包裝就是乙個希望將某個物件(或類),進行重新打包,裝換成另外一種更適合當前使用場合的對外介面。相似娛樂界對明星的包裝一樣,其實本質沒有什麼改變,只是表面變得更容易受當下人歡迎而已。用到程式程式設計中,就是將程式包裝成,當前環境跟適合的樣子(主要是對外介面)。

乙個例子,假如乙個類中包含了許多的資料屬性,同時也包含了許多的基本操作函式,但是我們要求得這個類的物件的某個值(來自於對這個類物件中的各個資料屬性和操作函式的多次操作),那麼是不是每次都需要做一遍這樣的事情呢?理論上是這樣的,有人會說,那為什麼不在當初定義類的時候就定義乙個這樣的函式呢?對!但是,當初定義的時候或許想不到這些,而更為重要的是,如果將某個類定義的過分應用於某個情景,那麼這個類就並不好在其他地方使用,而如果把它實際到適合在許多情景中使用,那又會是類變得特別的負責,所以基本上,我們認為類應該設計的比較基本為好。

所以,有沒有解決這一問題的辦法呢?有,那就是封裝!

在不同的應用場景將那個各個方法都較為基礎的類包裝成乙個適合在該地方使用的包裝類。

那麼包裝這個設計思想有哪些方法和以實現呢?

我們說既然是物件導向設計,那自然不能脫離類來講咯(實際上包裝的物件可以是任何物件)。我們找方法的範圍也減少了。這樣包裝的概念就是將乙個類所能幹的事情,通過不同的方式轉換成另外乙個類,它們的內容本質(這裡主要是說資料資訊)不變,只是對外操作的介面做了相應的轉變,或者新增了,或者減少了,或者轉變了,或者限制了等等。

乙個類與另外乙個類的關係只有兩種一種是繼承關係(包括祖先),另外一種是包含的關係。也就是derivation和composition兩種關係。

通過繼承的方式似乎可以,將原來的類成員先全部繼承,然後可以對函式進行重寫覆蓋,也可以新增性函式等等。這是乙個好方法,但是,在有些程式語言中如python2.2之前,基本資料型別不屬於類,那樣就不能被類繼承,就不能進行所謂的包裝。

所以還可以通過另外乙個方法來做到一點,那就是建立乙個類,而這個類往往只包含乙個資料成員物件,那就是它要封裝的類的物件。通俗的講,就是讓這個封裝類包含這個被封裝類的例項。然後通過在這個封裝類中各種方法的設定,實質上就是從這個包含物件的介面傳遞、轉換其相應的功能到這個包裝類上。讓外界感覺似乎就是在操作該被封裝的類一樣。可以看出,封裝類在轉換的時候有很多彈性,所以完全可以做到前面所說的包裝效果。

其實,我們可這麼想,在type和class還不是一回事的時候,我們沒有辦法使用繼承的方法來對基本資料型別進行封裝,所以只能通過這個手段了。但是現在type和class的統一是基本趨勢。但仍然不會有違通過composition的方法來進行包裝。實際上兩種包裝手段可以呈現出一種互補的態勢,可能大家有一些各自不適合的地方。

而授權是包裝的乙個特性,授權的過程,就是說所有的更新的功能都是由新類的某部分來處理,但已存在的功能就授權給物件的預設屬性。而實現這一功能的關鍵便是getattr() 特殊方法。這個方法的作用是:當試圖訪問乙個例項的屬性時,本地屬性會首先被找到,如果本地沒有就會去類屬性和祖先類屬性裡找,如果那裡也沒有的話,就會呼叫例項的 _getattr_() 方法。因此這裡就給我們提供了乙個將屬性訪問重定向到被包裝的型別(偽父類)的機會。其具體的實現方法便是,在getattr() 中呼叫內建的 getattr() 函式:

下面是乙個例子,這個例子在原有的類的基礎上,增加了幾個功能,也就是得到類的建立時間(ctime),修改時間(mtime)和訪問時間(atime)

from time import time,ctime

class

timedwrapme

(object):

def__init__

(self,obj):

self.__data=obj

self.__ctime=self.__mtime=self.__atime=time()

defget(self):

self.__atime=time()

return self.__data

defgettimeval

(self,t_type):

ifnot isinstance(t_type,str) or t_type[0] not

in'cma':

raise typeerror("argument of 'c','m','a' req'd' ")

print('_%s__%stime' % (self.__class__.__name__,t_type[0]))

return getattr(self,'_%s__%stime' % (self.__class__.__name__,t_type[0]))#attention!get private data attribute

defgettimestr

(self,t_type):

return ctime(self.gettimeval(t_type))

defsetr

(self,obj):

self.__data=obj

self.__mtime=self.__atime=time()

def__repr__

(self):

self.__atime=time()

return

'self.__data'

def__str__

(self):

self.__atime=time()

return str(self.__data)

def__getattr__

(self, item):

self.__atime=time()

return getattr(self.__data,item)

a=timedwrapme(9)

print(getattr(a,'_timedwrapme__ctime'))

print(a.gettimestr('c'))

print(repr(a))

下面還有乙個例子,實現以大寫的形式往檔案寫入:

在寫這個例子的時候遇到了點問題

class

upperopen

(object):

def__init__

(self,filename,mode='r',buf=-1):

self.file=open(filename,mode,buf)

def__str__

(self):

return str(self.file)

def__repr__

(self):

return repr(self.file)

defwrite

(self,line):

self.file.write(line.upper())

def__getattr__

(self, attr):

return getattr(self.file,attr)

f=upperopen('in.txt','w')

f.write('fdsa dsa fd afewqr dsaf e\n')

f.write('i am good')

f.close()

f=upperopen('in.txt','r')

for line in f:

print(line)

像上面這樣寫的時候在3.4.3下,會提示如下錯誤,說f不能迭代

如果顯示的呼叫iter函式的話是可以的:

f=upperopen('in.txt','r')

it=f.__iter__()

forline

init:

print(line)

或者重寫iter函式也是可以的

class

upperopen

(object):

def__init__

(self,filename,mode='r',buf=-1):

self.file=open(filename,mode,buf)

def__str__

(self):

return str(self.file)

def__repr__

(self):

return repr(self.file)

def__iter__

(self):

return self.file.__iter__()

defwrite

(self,line):

self.file.write(line.upper())

def__getattr__

(self, attr):

return getattr(self.file,attr)

f=upperopen('in.txt','w')

f.write('fdsa dsa fd afewqr dsaf e\n')

f.write('i am good')

f.close()

f=upperopen('in.txt','r')

for line in f:

print(line)

但是getattr不應該會搜尋到self.file的

__iter__

屬性嗎,不明白為什麼這樣不行,在《python程式設計思想 第二版》上,就是那麼寫的也沒有問題,難道又是因為我下的是3.4.3?希望哪位python大神指點

python的包裝和授權

包裝 python為大家提供了標準資料型別,以及豐富的內建方法,其實在很多場景下我們都需要基於標準資料型別來定製我們自己的資料型別,新增 改寫方法,這就用到了我們剛學的繼承 派生知識 其他的標準型別均可以通過下面的方式進行二次加工 包裝 二次加工標準型別 繼承 派生 的方式實現 定製功能 2 定製新...

python許可權授權 Python包裝授權

1 什麼是包裝 coding utf 8 包裝類,就是給被包裝的類加個殼 被包裝內實現殼的內部,而包裝內提供殼的外部 介面 有點類似於繼承關係,不過也不完全時,因為通過繼承也可以實現包裝效果,不使用繼承同樣可以實現包裝效果。下面通過乙個例子來展示 包裝的概念 class packagelist ob...

python類 包裝 授權

包裝 是指對乙個已經存在的物件進行系定義加工。實現授權是包裝的乙個特性。包裝乙個型別通常是對已存在的型別進行一些自定義定製,這種做法可以新建,修改,或刪除原有產品的某些功能,而其他的保持不變。授權的過程,其實也就是所有的更新功能都交給新類的自定義的某部分功能來處理,但已存在的功能就授權給物件的預設屬...