1樓:d41d8c
好問題。
這裡有趣的是a.__mul__(b) 是會成功的,因為b通過__index__方法轉換成了int。所以似乎違反了*運算子優先呼叫__mul__,如果返回NotImplemented才呼叫__rmul__的規則。
於是我看了原始碼。
cpython/abstract.c#L1106:
PyObject
*PyNumber_Multiply
(PyObject*v
,PyObject*w
)elseif(
mw&&
mw->
sq_repeat
)result
=binop_type_error(v
,w,"*");}
return
result;}
nb_multiply是int、float等數值型別以及自定義的class的乘法在 CPython 中的表示。sq_repeat是list、tuple等序列型別的乘法在 CPython 中的表示(這些型別故意沒有實現nb_multiply)。注意PyNumber_Multiply的第一行呼叫了nb_multiply(BINARY_OP1會嘗試兩個方向),而只有在第一行的結果是NotImplemented時才會考慮sq_repeat。
簡而言之就是序列的乘法會在數值的乘法之後考慮。
sq_repeat 的文件也寫到:
It is also used by the * operator, after trying numeric multiplication via the nb_multiply slot.
2樓:
對於兩個運算物件使用二元運算子相連線,Python會預設呼叫第乙個運算物件的運算子過載方法。
例如[1, 2, 3] * np.array([2]),實際上的運算邏輯為[1, 2, 3].__mul__(np.array([2]))。
如果第乙個運算物件呼叫該方法時返回NotImplemented,那麼會嘗試呼叫第二個運算物件的逆運算子過載方法。對於以上示例,實際上呼叫的是np.array([2]).
__rmul__([1, 2, 3])
檢查numpy原始碼可知,該方法返回乙個ndarray物件。
類似可以自定義所謂的型別轉換,以下是乙個示例:
class
Something
:def
__lshift__
(self
,other
(other
,end=''
)return
self
Something
()<<
4.9<<
'hello'
<<[1
,2,3
]輸出是4.9hello[1, 2, 3]
3樓:IT野狐禪
任何語言都沒有辦法處理使用者自定義型別的操作;它不會有合理的規則將自定義型別轉為基礎型別;np.array不是python自己的,出現*運算只能丟給自定義型別自己去處置;
如果運算子兩端都是python內建型別,它一般規則是向容量大的型別轉換;
python的邏輯運算子 and,or,not 和普通的邏輯運算子( )有何區別?
追遠 J 先糾正題主的乙個小錯誤。跟 同屬一家的運算子應該是 而非 這個問題還挺有意思 對問題本身的回答其實並不複雜 原則上講,and,or,not針對布林值 True False 進行運算,就是字面上的與或非的功能,確實可以稱之為邏輯運算子 類似C C 中的 而 則對應C C 中所謂的 按位運算子...
關於python中邏輯運算的小問題
李大師 上面的回答都很好,我也沒什麼必要再回答了,因為最近回答問題比較多,hit到limit,被賬號受限了幾天,對樓主提供乙個連線,你去那跟著看,這樣扣程式,扣幾天就有點心累了。一開始學習可以快速過一遍,然後找小作業做一下,小專案寫一下,然後過程中慢慢解決這些問題。Python 基礎程式設計 嗶哩嗶...
python如何實現左側的運算子過載?
Kittyhawk 先從myob 1說起,假設myob屬於Myob類,這裡我們過載了 mul class Myob def mul self val print mul 過載了 mul 後我們就可以順利實現myob 1,結果是列印出 mul 但如果把兩者換一下位,1 myob,就會報錯了。這是因為1...