python物件運算之間的資料隱藏轉換優先順序是怎麼確定的?

時間 2021-09-09 03:24:46

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

):print

(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...