Why implicitly check for emptiness in Python? [closed]

拥有回忆 提交于 2019-12-04 23:40:26
Yuval Adam

This best practice is not without reason.

When testing if object: you are basically calling the objects __bool__ method, which can be overridden and implemented according to object behavior.

For example, the __bool__ method on collections (__nonzero__ in Python 2) will return a boolean value based on whether the collection is empty or not.

(Reference: http://docs.python.org/reference/datamodel.html)

Possibly trumped by the first and third items:

  • Beautiful is better than ugly.
  • Simple is better than complex.

"Simple is better than complex."

"Readability counts."

Take for example if users -- it is more readable that if len(users) == 0

if c:
    # ...

is explicit. The "if" explicitly states that the expression following will be evaluated in boolean context.

It is fair to argue that

if c == 0:
    # ...

is clearer, and a programming novice might agree.

But to an experienced programmer (this one at least) the latter is not clearer, it is redundant. I already know c will be compared with 0 because of the "if"; I don't need to be told twice.

Implicit boolean polymorphism is a part of many languages. In fact, the idiom

if msg:
    print str(len(msg)) + ' char message: ' + msg

arguably comes from c!

void print_msg(char * msg) {
    if (msg) {
        printf("%d char message: %s", (int) strlen(msg), msg);
    }
}

An unallocated pointer should contain NULL, which conveniently evaluates to false, allowing us to avoid a segmentation fault.

This is such a fundamental concept that it would hamper python to reject it. In fact, given the fairly clumsy version of boolean polymorphism available in c, it's immediately clear (to me at least) that python has made this behavior much more explicit by allowing any type to have a customizable, well-defined boolean conversion via __nonzero__.

Jochen Ritzel

If you prefer you can type if len(lst) > 0, but what would be the point? Python does use some conventions, one of which is that empty containers are considered falseish.

You can customize this with object.__nonzero__(self):

Called to implement truth value testing and the built-in operation bool(); should return False or True, or their integer equivalents 0 or 1. When this method is not defined, __len__() is called, if it is defined, and the object is considered true if its result is nonzero. If a class defines neither __len__() nor __nonzero__(), all its instances are considered true.

Others have already noted that this is a logical extension of the tradition (at least as early as C, perhaps earlier) that zero is false in a Boolean context, and nonzero is true. Others have also already noted that in Python you can achieve some special effects with customized magic methods and such. (And this does directly answer your question "does it enable more use cases?") Others have already noted that experienced Python programmers will have learned this convention and be used to the convention, so it is perfectly obvious and explicit to them.

But honestly, if you don't like that convention, and you are just programming for your own enjoyment and benefit, simply don't follow it. It is much, much better to be explicit, clear, and redundant than it is to be obfuscated, and it's virtually always better to err on the side of redundancy than obfuscation.

That said, when it comes down to it, it's not a difficult convention to learn, and if you are coding as part of a group project, it is best to stick with the project's conventions, even if you disagree with them.

Empty lists evaluating to False and non-empty lists evaluating to True is such a central Python convention that it is explicit enough. If the context of the if-statement even communicates the fact that c is a list, len(c) == 0 wouldn't be much more explicit.

I think len(c) == 0 only is more explicit if you really want to check the length and not for magic zeroness or emptiness because their evaluation may differ from the length check.

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!