Live data from Hacker News

Common Python Mistakes

toptal.com

31–40 of 146 posts

Re: Common Python Mistakes

#32
post #21

Earlier quoted context omitted.

I have never wanted to declare a tuple without surrounding it with (). No? I do that occasionally, e.g.: x, y = 5, 6

Doing (x, y) = (5, 6) makes it clearer to "visually grep" that it's not a normal assignment though.

Fair enough, that would be fine by me.

Re: Common Python Mistakes

#33

Is the explanation for #1 correct? "when the default value for a function argument is an expression, the expression is evaluated only once" I would explain the behavior he shows as due to the default value being mutable . I don't see an expression there, just an empty list used as a default.

Actually, the explanation doesn't explain it all.

In Python, variables are references (pointers). `[]` gets evaluated on import time, and returns a pointer to an object (an empty list). This object is then further mutated on the body on the next calls because if you don't pass the parameter, it still points to the same object.

Re: Common Python Mistakes

#34

The scoping rules in #4, combined with being able to reference variables before definite assignment, is what leads to the 'variable hoisting' in Javascript. Is #6 really called 'late binding'? That seems like the wrong term.

Please check out http://en.wikipedia.org/wiki/Late_binding to know more.

I've always heard it used to refer to method dispatch, which that wikipedia article also seems to. However, it seems like the Python spec does use it to refer to when variable values are resolved.

Re: Common Python Mistakes

#35
post #29

> "Python is an interpreted, object-oriented, high-level programming language with dynamic semantics." I have an issue with that statement. No languages are inherently "compiled" or "interpreted", that's a property of the implementation. If we are talking about CPython here, Python code is compiled to bytecode which is then interpreted. Not unlike Java - with the difference that the main implementation has a JIT and…

> No languages are inherently "compiled" or "interpreted", that's a property of the implementation. A language and it's implementation are usually designed at the same time. Compiled or interpreted will affect design choices that go into the language. While additional implementations may follow, it can be hard/impossible to design a compiler (machine code, not byte code) for a language that was designed to be interpr…

Not really - Javascript was designed to be interpreted, and yet V8/SpiderMonkey/Nitro all JIT-compile it down to machine code, sometimes very effectively.

Re: Common Python Mistakes

#36
post #21

Earlier quoted context omitted.

I have never wanted to declare a tuple without surrounding it with (). No? I do that occasionally, e.g.: x, y = 5, 6

Doing (x, y) = (5, 6) makes it clearer to "visually grep" that it's not a normal assignment though.

It's the comma that determines an expression as a tuple, not the parentheseis.

Re: Common Python Mistakes

#37
This list is an excellent summary. If tasked with a #11 I'd probably add the slightly more obscure, but still super painful (when you do run into it) implicit string concatenation:

    >>> l = ["a",
    ...      "b",
    ...      "c"
    ...      "d"]
    >>> l
    ['a', 'b', 'cd']

Re: Common Python Mistakes

#38

For #7, now you have a performance problem of importing every time you run that function. Rather, you can place the import at the bottom of b.py and be okay.

The author states that Python is smart enough not to reimport a file that has already been imported. Is that not the case here?

Re: Common Python Mistakes

#39
This is a pretty good list of gotchas, but it's important when writing something targeted at beginners to be as precise and clear as possible. Nearly every section here either uses terminology poorly, is slightly incorrect, or has difficult examples.

  Python supports optional function arguments and allows default values to be 
  specified for any optional argument.
No, specifying a default is what causes an argument to be optional.

  it can lead to some confusion when specifying an expression as the default value
  for an optional function argument.
Anything you specify as a default value is an expression. The problem is when the default is mutable.

  the bar argument is initialized to its default (i.e., an empty list)
  only the first time that foo() is called
No, rather it's when the function is defined.

  class variables are internally handled as dictionaries
As dictionary keys, and that's still only roughly correct.

In "Common Mistake #5", he uses both a lambda and array index based looping, neither of which are particularly Pythonic. A better example of where this is a problem in otherwise Pythonic code would be good.

In "Common Mistake #6" he uses a lambda in a list comprehension -- for an article of mistakes mostly made by Python beginners, this is going to make it tough to follow the example.

In "Common Mistake #7", he describes "recursive imports" where he means "circular imports".

In "Common Mistake #8" he refers repeatedly to "stdlib" where he means the Python Standard Library. Someone is going to read that and try to "import stdlib".

Re: Common Python Mistakes

#40
Another one:

    class A():
      def __init__(self):
        self._x = 0
    
      @property
      def x(self):
        return self._x

      @x.setter
      def x(self, new_value):
        self._x = new_value
Using it:

    a = A()
    print a._x    # 0
    print a.x     # 0
    a.x = 4
    print a.x     # 4
    print a._x    # 0 wait WTF?!
The bug was not having `A` inherit from `object`. With old-style classes, properties do not work correctly.
Post reply on HN