Python之美[從菜鳥到高手]--NotImplemented小析

今天寫代碼時無意碰到NotImplemented,我一愣,難道是NotImplementedError的胞弟,所以稍微研究了一下。

NotImplemented故名思議,就是“未實現”,一般是用在一些比較算法中的,如class的__eq__,__lt__等,注意NotImplemented並不是異常,所以不能

使用raise,當沒有實現時應該是return NotImplemented。

我們可以看看django中的Field的實現,

@total_ordering
class Field(object):
    """Base class for all field types"""
    def __eq__(self, other):
        # Needed for @total_ordering
        if isinstance(other, Field):
            return self.creation_counter == other.creation_counter
        return NotImplemented

    def __lt__(self, other):
        # This is needed because bisect does not take a comparison function.
        if isinstance(other, Field):
            return self.creation_counter < other.creation_counter
        return NotImplemented

那提供NotImplemented有什麼好處?好處就在於如果A == B NotImplemented,會去調用B的__eq__方法,如果B也沒有會調用cmp方法。

我們看下面一個例子:

class Person:
    def __init__(self, age):
        self.age = age

    def __eq__(self, other):
        if not isinstance(other, Person):
            return NotImplemented
        return self.age == other.age

如果你們穩定庫中有這麼一段代碼,而且Person可能包含了很多字段,但是你想實現Person和整數比較。

person=Person(10)
print person == 10 #False
很遺憾,上面結果是False,不符合我們要求,至於爲什麼是10,稍後再說,我們先看看如何解決這個問題?

其實這時你可以簡單封裝一個age對象,

class Age:
    def __init__(self, age):
        self.age = age

    def __eq__(self, other):
        return self.age == other.age 

person=Person(10)
age=Age(10)
print person == age #True
ok,很完美,那我們從上面能得到什麼結論呢?

我們在寫一些基礎代碼時,即使是沒實現,也不要raise NotImplementedError,而是return NotImplemented,相當於提供給其它不同對象的比較接口,這對

代碼擴展非常有好處。


我們再來看看上面那麼直接和10比,爲什麼是False?

先看下面這段代碼:

class A:
    def __lt__(self, a):
        return NotImplemented

    def __add__(self ,a):
        return NotImplemented

print A() < A() # True
print A() < 1  # False
很奇怪吧,明明已經直接是NotImplemented,爲什麼還有結果?
大膽猜測,前面說明最後會使用cmp比較,很明顯當都沒有定義時會比較id值,也就是內存地址,後創建的對象內存地址大,就是這個道理。

至於A() < 1,因爲python的小整數對象在初始化時創建的,內存地址肯定小,如果你還不信,


不過千萬別搞沒有意思的操作,


這也是這位兄弟不解的地方,http://stackoverflow.com/questions/1062096/python-notimplemented-constant



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章