2011-06-06 79 views
8

在Python 2.7,我定義了一個空的新式類:的Python:默認比較

In [43]: class C(object): pass 
    ....: 

然後創建新類的實例列表:

In [44]: c = [C() for i in xrange(10)] 

然後嘗試排序列表:

In [45]: sorted(c) 
Out[45]: 
[<__main__.C object at 0x1950a490>, 
<__main__.C object at 0x1950a4d0>, 
... 
<__main__.C object at 0x1950aad0>] 

令人驚訝的是,排序不抱怨,即使我沒有定義一種方法來比較instan的C CES:

In [46]: dir(C()) 
Out[46]: 
['__class__', 
'__delattr__', 
'__dict__', 
'__doc__', 
'__format__', 
'__getattribute__', 
'__hash__', 
'__init__', 
'__module__', 
'__new__', 
'__reduce__', 
'__reduce_ex__', 
'__repr__', 
'__setattr__', 
'__sizeof__', 
'__str__', 
'__subclasshook__', 
'__weakref__'] 

究竟是什麼發生的事情,並什麼是這樣做的理由 - 可以說是驚人的 - 行爲?

回答

14

我認爲唯一的理由是便利的是,對象可以被排序,例如用作具有某些默認行爲的字典鍵。語言定義中的相關章節如下:https://docs.python.org/2/reference/expressions.html#not-in

「一個對象被認爲是小於還是大於另一個的選擇是任意的,但在程序的一次執行中是一致的。」

因此,目前使用內存地址比較對象的事實只是一個無法計算的實現細節。唯一的保證是訂單在執行期間保持一致。

+0

(+1)爲鏈接和報價。 – NPE 2011-06-06 13:59:58

+0

+1,你在評論中是完全正確的我被兩個對象和其他比較運算符的等同性誤導了,謝謝你計算出我的錯誤 – mouad 2011-06-06 14:19:33

+0

更新後的鏈接http://docs.python.org/reference/expressions.html #未在 – 2016-03-22 14:00:01

0

查看打印時的值。注意「Object C at」旁邊的十六進制數字?這是一個指針引用。它大致可以等同於創作順序。如果您遍歷該列表,您會看到它已經使用該標準對對象進行了排序。

作爲一個方面說明,我記得Python2x比較中的confused ......但我不知道這是否特別在Py3k中得到修復。

+0

是的,我注意到了。但是,基本原理是什麼? – NPE 2011-06-06 13:34:42

+1

@aix請參閱編輯。 Python <3使得比較幾乎煩人地容易。請參閱http://stackoverflow.com/questions/4266918/why-is-int50str5-in-python-2-x – cwallenpoole 2011-06-06 13:42:07

+0

原理是python中的變量是對堆中對象的引用。按內存地址排序可能是實現Python開發人員可以想到的默認行爲的最簡單方法。 – 2011-06-06 13:45:32

1

我不完全確定,但也許有人可以糾正我這一點。

比較對象時,它比較它們的內存地址,比較C中比較2個cstrings。如果看一下,排序將對象從最低內存地址排序到最高內存地址(或指針位置)。

+0

的確,但是這似乎沒有任何意義,因此也不是Pythonic? – NPE 2011-06-06 13:36:17

+0

那麼,在底層的C代碼中,當你比較2個對象時,它只是比較2個整數,它指向存儲對象的內存,我們都知道整數比較是如何工作的。 – Pwnna 2011-06-06 13:58:02