Boolean comparison & PEP8

Richard Damon Richard at Damon-Family.org
Sun Jul 28 20:42:25 EDT 2019


On 7/28/19 8:25 PM, Chris Angelico wrote:
> On Mon, Jul 29, 2019 at 10:15 AM Richard Damon <Richard at damon-family.org> wrote:
>> On 7/28/19 7:46 PM, Michael Torrie wrote:
>>> On 7/28/19 5:55 AM, Jonathan Moules wrote:
>>>> But this appears to be explicitly called out as being "Worse" in PEP8:
>>>>
>>>> """
>>>> Don't compare boolean values to True or False using ==.
>>>>
>>>> Yes:   if greeting:
>>>> No:    if greeting == True:
>>>> Worse: if greeting is True:
>>>> """
>>> Yet the recommended solution to the problem of wanting a default
>>> argument of an empty list is something like this:
>>>
>>> def foo(bar=False);
>>>     if bar is False:
>>>         bar = []
>>>
>>>     ....
>>>
>>> Clearly in this case the expression "not bar" would be incorrect.
>>>
>>> There's a difference between looking for a particular identity or
>>> sentinel, and checking for truthiness or falsiness.
>>>
>>> So I guess it all depends on what you need to do. If you just need to
>>> check truthiness, just do "if greeting"  If you need to know if the
>>> variable is some particular sentinel, use the "if greeting is whatever".
>> I thought the recommended value was None, not False (so you don't need
>> to ask why not True). I suppose if None is a valid value for the input
>> you would need something else, and False is one possibility.
>>
> In that situation, you'd be more likely to use a dedicated sentinel object:
>
> _SENTINEL = object()
> def foo(bar=_SENTINEL):
>     if bar is _SENTINEL: bar = []
>
> But there is a not-too-rare situation where you'd want to check if
> something "is False", and that's some form of three-valued logic, eg
> "true, false, and unspecified". For instance:
>
> def foo(verbose=None):
>     if verbose is False:
>         # caller specifically wanted quiet mode
>
>     if verbose is True:
>         # caller specifically wanted verbose mode
>
> Of course, if the third value can be simplified away (eg None means
> "use the global default"), then you can still just use "if verbose is
> None:" and then reassign it. But this is a legit reason to use "is
> False".
>
> ChrisA

The more common way to handle the 3 value case in my experience is to
first handle the 'special case' (check for None in your example) and
then use the normal truthiness test.

Then you example would be:

def foo(verbose=None):

    if verbose is None:

        # Didn't specify verbosity

    elif verbose:

      # Specified Verbose case

   else:

      # Specified none Verbose case


Do you REALLY mean that foo(0) is to be different than foo(false)?



-- 
Richard Damon




More information about the Python-list mailing list