The Zen of Python说“明确胜过隐性”。然而,用于检查空虚的“pythonic”方法是使用隐含的booleaness:
if not some_sequence:
some_sequence.fill_sequence()
如果some_sequence
是空序列,但如果它是None
或0
,则会出现这种情况。
与理论明确空虚检查比较:
if some_sequence is Empty:
some_sequence.fill_sequence()
对于一些不利的选择变量名称,检查空虚的隐含booleaness会变得更加混乱:
if saved:
mess_up()
与:比较:
if saved is not Empty:
mess_up()
另见:“Python: What is the best way to check if a list is empty?”。我觉得具有讽刺意味的是,投票最多的答案声称隐含的是pythonic。
为什么没有明确的空白检查有更高的理由,例如Python中的is Empty
?
答案 0 :(得分:22)
if foo:
和if not foo:
中的多态性不违反“隐式vs显式”:它显式委托给被检查对象的任务,知道它是否属实或者是假的。这意味着什么(以及如何最好地检查它)显然确实并且必须依赖于对象的类型,因此样式指南要求委托 - 让应用程序级代码傲慢地断言它比对象更好地知道愚蠢的高度。
此外,X is Whatever
总是,总是意味着X Empty
或Whatever
的任何其他特定值制作一个完全唯一的例外将是荒谬的 - 很难想象一个更加非语言的方法。并且“完全相同的对象”显然是可传递的 - 所以你再也不能拥有不同的空列表,空集,空的序列......祝贺你,你刚刚设计了一个完全无法使用和无用的语言,每个空容器疯狂地“折叠”到一个空的容器对象(想象一下当有人试图改变一个空容器时的乐趣......?!)。
答案 1 :(得分:14)
一旦您了解了is Empty
运算符的作用,没有is
的原因非常简单。
运算符
is
和is not
测试对象标识:x is y
为真 当且仅当x
和y
是同一个对象时。x is not y
产生了 反向真值。
这意味着some_sequence is Empty
会检查some_sequence
是否与Empty
是同一个对象。这不符合你的建议。
考虑以下示例:
>>> a = []
>>> b = {}
现在让我们假装在python中有这个is Empty
构造:
>>> a is Empty
True
>>> b is Empty
True
但是,由于is
运算符执行身份检查,这意味着a
和b
与Empty
相同。反过来,这必须意味着a
和b
是相同的,但它们不是:
>>> a is b
False
所以回答你的问题“为什么python中没有is Empty
?”:因为is
进行身份检查。
为了拥有is Empty
构造,你必须破解is
运算符以表示其他东西或者创建一些神奇的Empty
对象,它以某种方式检测空集合然后与它们相同
您应该问为什么没有调用特殊方法is Empty
的内置函数isempty()
,而不是问为什么没有__isempty__()
。
所以不要使用隐含的booleaness:
if saved:
mess_up()
我们有明确的空检查:
if not isempty(saved):
mess_up()
saved
的类具有__isempty__()
方法,以实现某些理智的逻辑。
我发现这比使用隐含的booleaness进行清空检查要好得多。
当然,您可以轻松定义自己的isempty()
功能:
def isempty(collection):
try:
return collection.__isempty__()
except AttributeError:
# fall back to implicit booleaness but check for common pitfalls
if collection is None:
raise TypeError('None cannot be empty')
if collection is False:
raise TypeError('False cannot be empty')
if collection == 0:
raise TypeError('0 cannot be empty')
return bool(collection)
然后定义一个__isempty__()
方法,该方法为所有集合类返回一个布尔值。
答案 2 :(得分:5)
我同意有时if foo:
对我来说并不明确,因为我真的想告诉读者这段代码我正在测试它的空虚。在这些情况下,我使用if len(foo):
。足够明确。
我100%同意Alex w.r.t is Empty
是unpythonic。
答案 3 :(得分:0)
考虑到Lisp一直使用()空列表或其符号NIL几年作为False和T或任何非NIL作为True,但通常计算Truth已经产生了一些有用的结果,如果需要则不需要重现。看看字符串的分区方法,其中中间结果非常好用,而非空控件是True约定。
我一般都试着避免使用len,因为它在紧密循环中非常昂贵。在程序逻辑中更新结果的长度值而不是重新计算长度通常是值得的。
对我来说,我更喜欢Python将False设为()或[]而不是0,但就是这样。那么使用not []作为非空是更自然的。但是now()不是[]是True所以你可以使用:
emptyset = set([])
if myset == emptyset:
如果你想明确空集的情况(不是我的设置([]))
我自己非常喜欢 if my myset 作为我的评论者。
现在我想到这可能是最接近显式的not_empty:
if any(x in myset for x in myset): print "set is not empty"
所以空是:
if not any(x in myset for x in myset): print "set is empty"
答案 4 :(得分:0)
是Python中可迭代的显式空白检查。拼写为not
。隐含在那里的是什么?当iterable为空时not
给出True,当非空时给出False。
你究竟反对什么?一个名字?正如其他人告诉你的那样,它肯定比is Empty
好。并不是那么不合理:考虑到Python中通常命名的东西,我们可能想象一个名为widgets
的序列,令人惊讶地包含一些小部件。然后,
if not widgets:
可以理解为“如果没有小部件......”。
或者你反对这个长度?明确并不意味着冗长,这是两个不同的概念。 Python没有addition
方法,它有+
运算符,如果您知道要应用它的类型,则它是完全明确的。与not
相同的事情。