为什么“如果不是某个对象:"比“if someobj == None:"好在 Python 中? [英] Why is "if not someobj:" better than "if someobj == None:" in Python?

查看:39
本文介绍了为什么“如果不是某个对象:"比“if someobj == None:"好在 Python 中?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我见过几个这样的代码示例:

如果不是某个对象:#做一点事

但我想知道为什么不这样做:

if someobj == None:#做一点事

有什么区别吗?一个比另一个有优势吗?

解决方案

在第一个测试中,Python 尝试将对象转换为 bool 值,如果它不是一个.粗略地说,我们在问对象:你有意义吗?这是使用以下算法完成的:

  1. 如果对象有一个 __nonzero__ 特殊方法(如数字内置函数,intfloat),它会调用这种方法.它必须要么返回一个 bool 值然后直接使用,要么返回一个 int 值,如果等于 0,它被认为是 False.

  2. 否则,如果对象有一个 __len__ 特殊方法(如容器内置函数,listdictset, tuple, ...),它调用这个方法,考虑容器False如果它是空的(长度为零).>

  3. 否则,对象被认为是True,除非它是None,在这种情况下,它被认为是False.

在第二个测试中,将对象与None 的相等性进行比较.在这里,我们询问对象,你是否等于另一个值?"这是使用以下算法完成的:

  1. 如果对象有 __eq__ 方法,则调用它,然后将返回值转换为 bool 值并用于确定结果if.

  2. 否则,如果对象具有 __cmp__ 方法,则调用它.此函数必须返回一个 int 指示两个对象的顺序(-1 if self < other, 0> if self == other, +1 if self > other).

  3. 否则,将比较对象的身份(即,它们是对同一对象的引用,可以通过 is 运算符进行测试).

使用 is 运算符可以进行另一个测试.我们会问这个对象,你是这个特定的对象吗?"

一般来说,我建议对非数字值使用第一个测试,当您想比较相同性质的对象(两个字符串、两个数字……)并检查是否存在相等性时,使用相等性测试仅在使用标记值时标识(例如,None 表示未为成员字段初始化,或者在使用 getattr__getitem__ 方法时).

总而言之,我们有:

<预><代码>>>>A类(对象):... def __repr__(self):...返回'A()'... def __nonzero__(self):...返回假>>>B类(对象):... def __repr__(self):...返回'B()'... def __len__(self):...返回0>>>C类(对象):... def __repr__(self):...返回'C()'... def __cmp__(self, other):...返回0>>>D类(对象):... def __repr__(self):...返回'D()'... def __eq__(self, other):...返回真>>>对于 ['', (), [], {}, 0, 0., A(), B(), C(), D(), None] 中的 obj:... 打印 '%4s: bool(obj) ->%5s, obj == 无 ->%5s, obj 是 None ->%5s' % \... (repr(obj), bool(obj), obj == None, obj is None)'': bool(obj) ->错误,obj == 无 ->错误,obj 是 None ->错误的(): bool(obj) ->错误,obj == 无 ->错误,obj 是 None ->错误的[]: bool(obj) ->错误,obj == 无 ->错误,obj 是 None ->错误的{}: bool(obj) ->错误,obj == 无 ->错误,obj 是 None ->错误的0: bool(obj) ->错误,obj == 无 ->错误,obj 是 None ->错误的0.0: bool(obj) ->错误,obj == 无 ->错误,obj 是 None ->错误的A(): bool(obj) ->错误,obj == 无 ->错误,obj 是 None ->错误的B(): bool(obj) ->错误,obj == 无 ->错误,obj 是 None ->错误的C(): bool(obj) ->是的,obj == 无 ->是的,obj 是 None ->错误的D(): bool(obj) ->是的,obj == 无 ->是的,obj 是 None ->错误的无:bool(obj) ->错误,obj == 无 ->是的,obj 是 None ->真的

I've seen several examples of code like this:

if not someobj:
    #do something

But I'm wondering why not doing:

if someobj == None:
    #do something

Is there any difference? Does one have an advantage over the other?

解决方案

In the first test, Python try to convert the object to a bool value if it is not already one. Roughly, we are asking the object : are you meaningful or not ? This is done using the following algorithm :

  1. If the object has a __nonzero__ special method (as do numeric built-ins, int and float), it calls this method. It must either return a bool value which is then directly used, or an int value that is considered False if equal to zero.

  2. Otherwise, if the object has a __len__ special method (as do container built-ins, list, dict, set, tuple, ...), it calls this method, considering a container False if it is empty (length is zero).

  3. Otherwise, the object is considered True unless it is None in which case, it is considered False.

In the second test, the object is compared for equality to None. Here, we are asking the object, "Are you equal to this other value?" This is done using the following algorithm :

  1. If the object has a __eq__ method, it is called, and the return value is then converted to a boolvalue and used to determine the outcome of the if.

  2. Otherwise, if the object has a __cmp__ method, it is called. This function must return an int indicating the order of the two object (-1 if self < other, 0 if self == other, +1 if self > other).

  3. Otherwise, the object are compared for identity (ie. they are reference to the same object, as can be tested by the is operator).

There is another test possible using the is operator. We would be asking the object, "Are you this particular object?"

Generally, I would recommend to use the first test with non-numerical values, to use the test for equality when you want to compare objects of the same nature (two strings, two numbers, ...) and to check for identity only when using sentinel values (None meaning not initialized for a member field for exemple, or when using the getattr or the __getitem__ methods).

To summarize, we have :

>>> class A(object):
...    def __repr__(self):
...        return 'A()'
...    def __nonzero__(self):
...        return False

>>> class B(object):
...    def __repr__(self):
...        return 'B()'
...    def __len__(self):
...        return 0

>>> class C(object):
...    def __repr__(self):
...        return 'C()'
...    def __cmp__(self, other):
...        return 0

>>> class D(object):
...    def __repr__(self):
...        return 'D()'
...    def __eq__(self, other):
...        return True

>>> for obj in ['', (), [], {}, 0, 0., A(), B(), C(), D(), None]:
...     print '%4s: bool(obj) -> %5s, obj == None -> %5s, obj is None -> %5s' % \
...         (repr(obj), bool(obj), obj == None, obj is None)
  '': bool(obj) -> False, obj == None -> False, obj is None -> False
  (): bool(obj) -> False, obj == None -> False, obj is None -> False
  []: bool(obj) -> False, obj == None -> False, obj is None -> False
  {}: bool(obj) -> False, obj == None -> False, obj is None -> False
   0: bool(obj) -> False, obj == None -> False, obj is None -> False
 0.0: bool(obj) -> False, obj == None -> False, obj is None -> False
 A(): bool(obj) -> False, obj == None -> False, obj is None -> False
 B(): bool(obj) -> False, obj == None -> False, obj is None -> False
 C(): bool(obj) ->  True, obj == None ->  True, obj is None -> False
 D(): bool(obj) ->  True, obj == None ->  True, obj is None -> False
None: bool(obj) -> False, obj == None ->  True, obj is None ->  True

这篇关于为什么“如果不是某个对象:"比“if someobj == None:"好在 Python 中?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆