編寫符合Python風格的物件

2021-09-14 03:13:17 字數 2872 閱讀 5432

1、掌握編寫pythonic code背後常用的特殊方法;

2、掌握可擴充套件的格式化輸出方法;

3、了解可雜湊物件的設定以及節省記憶體的__slots__物件。

自定義的向量類需要支援基本的輸出,迭代,求模。

從自定義向量型別入手寫出符合python風格的物件,這離不開特殊方法的支援。

我們期望的自定義向量型別應支援的基本功能:

**實現如下:

import math

from array import array

class vector2d:

typecode='d'

def __init__(self,x,y):

self.x=float(x)

self.y=float(y)

def __str__(self):

return str(tuple(self))

def __iter__(self):

return (i for i in (self.x,self.y))

def __repr__(self):

classname=type(self).__name__

s="{}({},{})".format(classname,*self)

return s

def __abs__(self):

return math.hypot(self.x,self.y)

def __bytes__(self):

return (bytes(self.typecode,encoding='utf-8')+

bytes(array(self.typecode,self)))

我們能將例項轉化為位元組序列,那麼也應構造乙個將例項轉化為位元組序列的方法。

@classmethod

def frombytes(cls,seqs):

typecode=chr(seqs[0])

memv=memoryview(seqs[1:]).cast(typecode)

return cls(*memv)

memoryview是泛化和去數學化的陣列。

classmethod:定義操作類而不是操作例項的方法,類方法的第乙個引數是類本身而不是例項。最常見的用途是定義備選構造方法(返回cls(*))

staticmethod:是普通的函式,只是碰巧在類的定義體中,而不是在模組層定義。

通過改寫format背後的__format__可以寫出可擴充套件的格式。

例項1:實現format對向量類的處理

def __format__(self,fmt_spec=''):

components=(format(v,fmt_spec)for v in self)

return "({},{})".format(*components)

例項2:通過尾部自定義格式**p實現將直角座標向量轉化為極座標向量。

def __format__(self,fmt_spec=''):

if fmt_spec[-1]=="p":

coord=(abs(self),self.angle())

spec=fmt_spec[:-1]

components=(format(v,spec)for v in coord)

outer="<{},{}>"

else:

coord=self

components = (format(v, fmt_spec) for v in self)

outer = "({},{})"

return outer.format(*components)

本段**的重點在於判斷格式中是否存在自定義格式符p,並進行對應的格式處理。

目前的向量是不可雜湊的,而可雜湊物件需要滿足:

(1)支援hash()函式,並且通過hash()得到的雜湊值是不變的;

(2)支援通過__eq__()方法來檢測相等性;

(3)若a==b為真,則hash(a)=hash(b)也為真。

所以我們需要把物件定為不可變,然後自定義__hash__。

通過使用兩個前導下劃線。將屬性標記為私有的。

@property

def x(self):

return self.__x

@property

def y(self):

return self.__y

使用異或運算子實現。

def __hash__(self):

return hash(self.x)^hash(self.y)

預設情況下,python在各個例項中名為__dict__的字典中儲存例項屬性,相應地會消耗大量記憶體。

通過__slots__類屬性,並讓直譯器把例項屬性儲存在元組中,可以節省大量記憶體。

class vector2d:

__slots__ = ('__x','__y')

typecode='d'

#其他方法實現省略

使用__slots__應注意的問題:

當處理的例項規模較小時,禁止建立動態屬性或不支援弱引用是比較好的選擇。

通過建立子類可以把繼承自父類的例項屬性覆蓋掉。

class shortvector2d(vector2d):

typecode = 'f'

#其它方法實現省略

符合Python風格的物件

python的私有屬性和受保護的屬性 如果有人編寫了dog類,這個類內部用到了mood例項屬性,但是沒有將其開放。現在,你建立了dog類的子類 beagle。如果你在毫不知情的情況下又建立了名為mood的例項屬性,那麼在繼承的方法中就會把dog類的mood屬性覆蓋掉。名稱改寫 為了避免這個情況,如果...

Python的編寫風格 縮排及注釋

python語言是以縮進來標識 塊的,如在迴圈 for 和判斷 if else 中,如果不使用縮排規則就會發生錯誤。那麼如何產生縮排的效果呢?答案是使用tab鍵或空格即可。使用時可以從兩者取其一,極不建議兩者混合使用。建議大家使用4個空格作為縮排。如下條件語句 score 90if score 60...

程式的編寫風格

程式設計風格雖然不會影響程式的功能,但會影響可讀性。程式的版式追求清晰 美觀,是程式風格的重要構成因素。空行起著分隔程式段落的作用。空行得體 不能過多也不能過少 將使程式的布局更加清晰。空行不會浪費記憶體,雖然列印含有空行的程式是會多消耗一些紙張,但是值得。所以不要捨不得用空行。在每個類宣告之後 每...