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