19

In some other languages I knows, the intuitive result of a null to string conversion should be an empty string. Why Python is designed to make 'None' be sort of special string? And this can lead to extra work when checking a return value from a function

result = foo() # foo will return None if failure 
if result is not None and len(str(result)) > 0:
    # ... deal with result 
    pass 

if str(None) returns empty string, the code could be shorter:

if len(str(result)) > 0:
    # ... deal with result 
    pass 

Looks like Python is trying to be verbose, to make log files be more understandable?

Rob Lao
  • 1,526
  • 4
  • 14
  • 38
  • 6
    This doesn't really answer your question, but it does circumvent your problem. `bool(None) == False`, but _also_ `bool('') == False`. So in reality you just have to check `if result: #pass`, as `''` and `None` both evaluate False. I'll try and find some reasoning for the choice of `str(None) == 'None'`, but I don't think it should impact your code if you're just checking if a proper string was returned. – pswaminathan Jul 17 '13 at 04:31
  • It's only extra work because the conditional you defined is awkward: "only deal with result if it's not None or its string representation is not empty". Use a more conventional way of checking (like suggested by @pswaminathan) and the problem goes away. – vanza Jul 17 '13 at 04:33
  • If `foo` returns `None` in case of failure, you need to check for `None`. In your example, anything whose string representation is empty is apparently handled the same was as `None`, but there's no particular reason why that should be the default behavior. The question is, why are you using "length of str(x)" as a diagnostic for anything? – BrenBarn Jul 17 '13 at 04:34
  • 1
    Actually I think this is a very good question. It's easy to see why `repr(None)` should be `'None'`, but why shouldn't `str(None)` be `''`? – Mark Ransom Jul 17 '13 at 04:37
  • 1
    @BobL: For the record, Python is not unique in this regard. For example, in Java, converting a `null` to a string results in the literal string `"null"`. Reference: [JLS 5.1.11](http://docs.oracle.com/javase/specs/jls/se7/html/jls-5.html#jls-5.1.11). – Daniel Pryden Jul 17 '13 at 04:39
  • `None` isn't some sort of special string; it's not a string at all. If `None` and `''` are both possible return values of a function, you probably don't want to handle them the same way. – user2357112 Jul 17 '13 at 06:26

2 Answers2

15

Checking if a string has characters in it by checking len(str(result)) is definitely not pythonic (see http://www.python.org/dev/peps/pep-0008/).

result = foo() # foo will return None if failure 
if result:
    # deal with result.
    pass

None and '' coerce to the boolean False.


If you are really asking why str(None) does return 'None', then I believe it is because it is necessary for three-valued logic. True, False and None can be used together to determine if a logical expression is True, False or cannot be decided. The identity function is the easiest for representation.

True  -> 'True'
False -> 'False'
None  -> 'None'

The following would be really weird if str(None) was '':

>>> or_statement = lambda a, b: "%s or %s = %s" % (a, b, a or b)
>>> or_statement(True, False)
'True or False = True'
>>> or_statement(True, None)
'True or None = True'
>>> or_statement(None, None)
'None or None = None'

Now, if you really want for an authoritative answer, ask Guido.


If you really want to have str(None) give you '' please read this other question: Python: most idiomatic way to convert None to empty string?

Community
  • 1
  • 1
dnozay
  • 23,846
  • 6
  • 82
  • 104
  • 2
    If you need a complete implementation of three-valued logic that uses True, False and None then check out the [Python Tribool module](http://www.grantjenks.com/docs/tribool/) – GrantJ Jun 05 '15 at 18:17
  • Expanding on @GrantJ 's statement, `or_statement()` as written is not a good tri-state example because it has a different result depending on argument order: `or_statement(None, False)` should be undecidable, ie `None` but returns `False` because `or` is a simple shortcut operator that falls through after the boolean coercion of `None` to `False`. – Metaxis Dec 14 '15 at 21:54
4

Basically, because an empty string isn't a representation of None. None is a special value that is distinct from an empty string or anything else. As described in the docs, str is supposed to

Return a string containing a nicely printable representation of an object.

Basically, str is supposed to return something printable and human-readable. An empty string would not be a readable representation of None.

BrenBarn
  • 242,874
  • 37
  • 412
  • 384
  • 3
    By that logic, `str(None)` and `str('None')` shouldn't be equal either. – Mark Ransom Jul 17 '13 at 04:43
  • @Mark How does that suggest that `str` should have anything to do with equality? It's just a value that you can print. Use `repr` if you need to distinguish the type/value as a string. – DanielB Jul 17 '13 at 04:49
  • @DanielB, I already expressed that sentiment in a comment on the question itself. – Mark Ransom Jul 17 '13 at 04:57