Hacker News new | past | comments | ask | show | jobs | submit login
Python’s misleading readability (nedbatchelder.com)
17 points by ingve on Jan 24, 2018 | hide | past | favorite | 14 comments



The second example, `if answer == "y" or "yes":` isn't even about Python - it's about understanding basic boolean notation, that takes directly from math. First example is similar - but coming from any programming language, you already know that comparison is `==` operator, and whatever `is` is, it's probably something else.


I think the sentence in the introduction, "Beginners construct valid Python expressions that don’t do what they seem like they should do.", is meant to include people who aren't coming from any programming language.


Yes, moreover, it should be a type error.


It isn't a type error:

  % python
  Python 3.6.0 ...
  >>> answer = "yes"
  >>> if answer == "y" or "yes":
  ...     print("Thanks")
  ...
  Thanks
The expression is the same as: (answer == "y") or "yes"

If answer is 'y' then the if-expression evaluates to True; for any other string it evaluates to "yes":

  >>> "y" == "y" or "yes"
  True
  >>> "yes" == "y" or "yes"
  'yes'
  >>> "no" == "y" or "yes"
  'yes'
Both True and 'yes' are considered True for an if-expression.


I think you read the parent as saying "I expect that Python currently reports this as a type error", which of course is not the case. I suspect, however, that the parent intended something more along the lines of "Other things being equal, the better language would reject this as a type error."


So the use case where you actually want that exact syntax is

"if a == someValue or someVariableIsNotNull"


It's puzzling that "x is 17" should work but then "1000 + 1 is 1001" doesn't.

The reason is that Python pre-allocates 262 numbers at initialization (-5 to 256) and the allocation uses a different method/structure for bigger numbers.

  >>> x = 256
  >>> x is 256
  True
  >>> id(x)
  94900419138400
  >>> id(256)
  94900419138400

  >>> x = 257
  >>> x is 257
  False
  >>> id(x)
  94900419504344
  >>> id(257)
  94900419504368
Reference: https://www.laurentluce.com/posts/python-integer-objects-imp...


I too find those comparisons confusing. Being a python programmer for 3 years now, I can see what actually made me keep learning it to the point I use it professionally, daily.

The language has enough mixes of advanced features that allowed me to curate what features I learned (and then used).

A classic example is the use of the logging module and decorators for login function calls. I did the whole thing I wanted to do without proper logging, but when I wanted to add logging to a few function calls, I simple research pointed me to using decorators and the logging module.

And so, more python goodness for myself. That led to other features such as the decorated classmethods and etc, but all in my own pace. That is something that I've only encountered with python.


After guiding beginners through Python, one crucial advantage it has over other language for beginners is good documentation (and a lot of it), and a readily available REPL. The beginner can quickly test different variables/data structures, observe that something's fishy, and then read the documentation to find out what the code is supposed to do. Contrast that to a beginner debugging a similar problem in, say C, which would be far more difficult.


tldr:

"is" checks for identity, not equality

"a == b or c" is different from "a == b or a == c"



Haha, no.


Sometimes Python leans to the DWIM side:

  >>> 42 is not None
  True
  >>> 'oo' in 'foobar'
  True
One could argue that both answers should be False, because:

  >>> 42 is (not None)
  False
  >>> 'oo' in iter('foobar')
  False


Sometimes ugly verbosity in programming languages is helpful, like 'is' -> 'isObject' or similar. Or choose a special Unicode symbol for every case. Unambiguous, but make sure you bury a Rosetta stone somewhere.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: