Python之美[从菜鸟到高手]--NotImplemented小析
2014-09-24 15:35
330 查看
http://blog.csdn.net/yueguanghaidao/article/details/38641251
分类: python2014-08-17
19:51 230人阅读 评论(0) 收藏 举报
今天写代码时无意碰到NotImplemented,我一愣,难道是NotImplementedError的胞弟,所以稍微研究了一下。
NotImplemented故名思议,就是“未实现”,一般是用在一些比较算法中的,如class的__eq__,__lt__等,注意NotImplemented并不是异常,所以不能
使用raise,当没有实现时应该是return NotImplemented。
我们可以看看django中的Field的实现,
[python] view
plaincopy
@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方法。
我们看下面一个例子:
[python] view
plaincopy
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和整数比较。
[python] view
plaincopy
person=Person(10)
print person == 10 #False
很遗憾,上面结果是False,不符合我们要求,至于为什么是10,稍后再说,我们先看看如何解决这个问题?
其实这时你可以简单封装一个age对象,
[python] view
plaincopy
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?
先看下面这段代码:
[python] view
plaincopy
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
分类: python2014-08-17
19:51 230人阅读 评论(0) 收藏 举报
今天写代码时无意碰到NotImplemented,我一愣,难道是NotImplementedError的胞弟,所以稍微研究了一下。
NotImplemented故名思议,就是“未实现”,一般是用在一些比较算法中的,如class的__eq__,__lt__等,注意NotImplemented并不是异常,所以不能
使用raise,当没有实现时应该是return NotImplemented。
我们可以看看django中的Field的实现,
[python] view
plaincopy
@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方法。
我们看下面一个例子:
[python] view
plaincopy
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和整数比较。
[python] view
plaincopy
person=Person(10)
print person == 10 #False
很遗憾,上面结果是False,不符合我们要求,至于为什么是10,稍后再说,我们先看看如何解决这个问题?
其实这时你可以简单封装一个age对象,
[python] view
plaincopy
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?
先看下面这段代码:
[python] view
plaincopy
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
相关文章推荐
- Python之美[从菜鸟到高手]--生成器之全景分析
- Python之美[从菜鸟到高手]--玩转描述符和属性
- Python之美[从菜鸟到高手]--NotImplemented小析
- Python之美[从菜鸟到高手]--生成器之全景分析
- Python之美[从菜鸟到高手]--玩转描述符和属性
- Python中的对象和动态性 [菜鸟的理解,高手莫入]
- 【转】Python之美[从菜鸟到高手]--urlparse源码分析
- Python之美[从菜鸟到高手]--2+2=5
- Python之美[从菜鸟到高手]--浅拷贝、深拷贝完全解读(copy源码分析)
- Python之美[从菜鸟到高手]--装饰器之使用情景分析
- Python之美[从菜鸟到高手]--深刻理解原类(metaclass)
- Python之美[从菜鸟到高手]--一步一步动手给Python写扩展(异常处理和引用计数)
- Python之美[从菜鸟到高手]--一步一步动手给Python写扩展(异常处理和引用计数)
- Python之美[从菜鸟到高手]--生成器之全景分析
- Python之美[从菜鸟到高手]--urllib源码分析
- Python之美[从菜鸟到高手]--生成器之全景分析
- Python之美[从菜鸟到高手]--一步一步动手给Python写扩展(爱之初体验)
- Python之美[从菜鸟到高手]--urlparse源码分析
- Python之美[从菜鸟到高手]--threading daemon线程原理解读
- Python之美[从菜鸟到高手]--NotImplemented小析