摘要:在中,特殊方法以雙下劃線開始,以雙下劃線結(jié)束。真假值,如果向量模為,返回實現(xiàn)向量加法實現(xiàn)向量乘法,例如返回向量的模返回歐幾里德范數(shù)找個例子運行下。怎么辦中有個特殊方法,可以修改控制臺輸出的樣式。
什么是特殊方法?當(dāng)我們在設(shè)計一個類的時候,python中有一個用于初始化的方法$__init__$,類似于java中的構(gòu)造器,這個就是特殊方法,也叫作魔術(shù)方法。簡單來說,特殊方法可以給你設(shè)計的類加上一些神奇的特性,比如可以進(jìn)行python原生的切片操作,迭代、連乘操作等。在python中,特殊方法以雙下劃線開始,以雙下劃線結(jié)束。
一個大例子數(shù)學(xué)中有一個表示數(shù)的概念叫做向量,但是python中的數(shù)據(jù)類型卻沒有。我們來設(shè)法用python實現(xiàn)它。
首先考慮,向量跟普通的數(shù)據(jù)類型不同,傳統(tǒng)的數(shù)可以直接進(jìn)行運算,向量則需要對不同的坐標(biāo)分別運算。來試試。
首先定義一個類,實現(xiàn)初始化方法。
# 實現(xiàn)向量類型 class Vector: def __init__(self, x=0, y=0): self.x = x self.y = y
如何實現(xiàn)向量的加法?二維向量中,向量的加法就是每個坐標(biāo)分別相加得到的結(jié)果。在python中有個$__add__$方法,用來進(jìn)行加法操作。
class Vector: def __init__(self, x=0, y=0): self.x = x self.y = y # 實現(xiàn)向量加法 def __add__(self, other): x = self.x + other.x y = self.y + other.y return Vector(x, y)
我們對x和y變量分別進(jìn)行相加,然后返回Vector。在python你可以對字符串直接用加法拼接起來的原理就在此,python實現(xiàn)了針對字符串的add方法。
實現(xiàn)了加法,乘法的道理一樣,分別對每個坐標(biāo)多帶帶相乘即可。
class Vector: def __init__(self, x=0, y=0): self.x = x self.y = y # 實現(xiàn)向量加法 def __add__(self, other): x = self.x + other.x y = self.y + other.y return Vector(x, y) # 實現(xiàn)向量乘法,例如r*3 def __mul__(self, scalar): return Vector(self.x*scalar, self.y*scalar)
我們在進(jìn)行向量運算時還有一個常用的操作是求向量的模,我們用$__abs__$特殊方法來實現(xiàn),abs一般用來求一個數(shù)的絕對值,向量用不到,用來求模剛好合適。使用math模塊中的hypot方法計算$sqrt(x^2+y^2)$。
class Vector: def __init__(self, x=0, y=0): self.x = x self.y = y # 真假值,如果向量模為0,返回false def __bool__(self): return bool(abs(self)) # 實現(xiàn)向量加法 def __add__(self, other): x = self.x + other.x y = self.y + other.y return Vector(x, y) # 實現(xiàn)向量乘法,例如r*3 def __mul__(self, scalar): return Vector(self.x*scalar, self.y*scalar) # 返回向量的模 # hypot()返回歐幾里德范數(shù) sqrt(x*x + y*y) def __abs__(self): return hypot(self.x, self.y)
找個例子運行下。
v = Vector(2, 3) print(v) v2 = Vector(4, 5) print(v+v2) print(v+v2*2)
<__main__.Vector object at 0x000002B4B1843C50> <__main__.Vector object at 0x000002B4B1843EF0> <__main__.Vector object at 0x000002B4B1843898>
可以運行了,貌似是正確的,但是輸出的結(jié)果很奇怪。怎么辦?python中有個$__repr__$特殊方法,可以修改控制臺輸出的樣式。
class Vector: def __init__(self, x=0, y=0): self.x = x self.y = y # 真假值,如果向量模為0,返回false def __bool__(self): return bool(abs(self)) # 實現(xiàn)向量加法 def __add__(self, other): x = self.x + other.x y = self.y + other.y return Vector(x, y) # 實現(xiàn)向量乘法,例如r*3 def __mul__(self, scalar): return Vector(self.x*scalar, self.y*scalar) # 返回向量的模 # hypot()返回歐幾里德范數(shù) sqrt(x*x + y*y) def __abs__(self): return hypot(self.x, self.y) # 實現(xiàn)__repr__方法,在控制臺打印向量時會輸出Vector(1, 2) # 實現(xiàn)__str__,使用str()返回字符串 def __repr__(self): return "Vector(%r, %r)" % (self.x, self.y)
實現(xiàn)了$__repr__$方法,我們就可以在控制臺輸出Vecotor(x,y)。與之對應(yīng)的有個$__str__$方法,使用str()返回相應(yīng)的字符串,展示給用戶。
現(xiàn)在來看下之前程序運行的結(jié)果。
v = Vector(2, 3) print(v) v2 = Vector(4, 5) print(v+v2) print(v+v2*2) print(abs(v))
Vector(2, 3) Vector(6, 8) Vector(10, 13) 3.605551275463989
效果不錯。
通過實現(xiàn)特殊方法,自定義類型可以表現(xiàn)的跟內(nèi)置類型一樣,讓我們能夠?qū)懗龈哂衟ython風(fēng)格的代碼。
除了上面說到的幾個特殊方法外,python還有差不多80多個特殊方法,比如$__len__$方法可以用來求長度,$__getitem__$可以使用haha[2]之類的操作進(jìn)行切片和迭代等,同樣的還有$__setitem__$。
本人才疏學(xué)淺,上文中難免有些錯誤,還請各位品評指正。如果覺得寫的還行,歡迎關(guān)注我的公眾號MLGroup,帶你走進(jìn)機器學(xué)習(xí)的世界。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://m.hztianpu.com/yun/44516.html
摘要:找出列表中小于的數(shù)據(jù)除了列表推導(dǎo)式,還有字典推導(dǎo)式,集合推導(dǎo)式,用法都一樣。如果你的數(shù)據(jù)量很大的話,考慮使用生成器表達(dá)式。切片不僅對列表有用,同樣適用于元組和字符串。切片命名使用方法,內(nèi)部參數(shù)與切片一樣。對剩余的的數(shù)據(jù),使用星號代替即可。 上次我們講了幾個不常見的數(shù)據(jù)類型,每個都有自己特殊的用途,雖然不經(jīng)常用到,了解一下也好。比如我們提到的數(shù)組類型,如果在數(shù)據(jù)量很大的時候同時要效率,就...
摘要:字典和集合都是基于散列表實現(xiàn)的,散列表也就是表,了解過數(shù)據(jù)結(jié)構(gòu)的應(yīng)該知道。而使用另一種辦法,任何鍵在找不到的情況下都會用中的值數(shù)據(jù)類型比如替換。在設(shè)計時就可以使用創(chuàng)建你的數(shù)據(jù)接口。 這次主要說說字典和集合這兩種數(shù)據(jù)類型。 字典和集合都是基于散列表實現(xiàn)的,散列表也就是hash表,了解過數(shù)據(jù)結(jié)構(gòu)的應(yīng)該知道。與散列表相關(guān)的一個概念叫做可散列,什么是可散列?在python官方定義中是這樣說的:...
摘要:擠掉了堆中實現(xiàn)了堆排序。你可以用堆排序來查找一個序列中最大的或者最小的幾個元素。除了使用堆排序,中還有排序和,這兩個排序最終生成以列表表示的排序結(jié)果,堆排序也是。 這次我們來說說python中的數(shù)據(jù)結(jié)構(gòu)。當(dāng)然了,不會講很基礎(chǔ)的內(nèi)容。 用過python的都知道,python有著與其他語言很不一樣的數(shù)據(jù)類型,像什么列表、元組、集合、字典之類。這些數(shù)據(jù)類型造就了python簡單易用同時又很強...
摘要:來說說迭代器和生成器,還有可迭代對象和生成器表達(dá)式。有點繞是不是,其實,一般只要知道可迭代對象以及它是如何實現(xiàn)的就行了,中常常用生成器來代替迭代器,可以說,生成器就是迭代器。 來說說迭代器和生成器,還有可迭代對象和生成器表達(dá)式。 之前簡單的提到過,一個對象是可迭代的可以理解為能夠使用for循環(huán)。這樣說其實不太準(zhǔn)確,某個對象可迭代是因為它內(nèi)部實現(xiàn)了$__iter__$這個特殊方法。比如在...
摘要:先不講數(shù)據(jù)結(jié)構(gòu)了,這次來說說中一些不被注意的功能。直接交換第二個功能。對的長度使用生成一個序列,然后遍歷或者這樣第三個功能。其實還接受第二個參數(shù),它的作用是在迭代的過程中如果碰到第二個參數(shù)則停止。 先不講數(shù)據(jù)結(jié)構(gòu)了,這次來說說python中一些不被注意的功能。 在python的設(shè)計哲學(xué)中,有這么一條內(nèi)容:Simple is better than complex,簡單的代碼比復(fù)雜的要好...
閱讀 3815·2021-11-24 09:39
閱讀 1948·2021-11-16 11:45
閱讀 669·2021-11-16 11:45
閱讀 1132·2021-10-11 10:58
閱讀 2573·2021-09-09 11:51
閱讀 1996·2019-08-30 15:54
閱讀 758·2019-08-29 13:13
閱讀 3521·2019-08-26 12:18