Live data from Hacker News

Common Python Mistakes

toptal.com

11–20 of 146 posts

Re: Common Python Mistakes

#11
post #5

Also, for the first example, it is a scope issue: def foo2(): def foo(a=[]): a.append('ba') return a return foo() print foo2() print foo2() print foo2() print foo2() print foo2() Gives ['ba'] ['ba'] ['ba'] ['ba'] ['ba']

I think the way he described it is pretty accurate. Default keyword arguments are only evaluated once at function definition, so supplying a mutable default keyword argument can cause issues.

Your example is pretty contrived and doesn't illustrate what he was pointing out, as you're creating a new function foo every time foo2 is called, and only calling it once.

Re: Common Python Mistakes

#12
#6 is really confusing. Whenever I encounter something like this my first reaction is that whenever possible such obscure components of a language should be avoided and more verbose/clear code used instead.

Programming languages are meant to be read as well as written, and someone relatively new to Python (and many who have used the language for a long time) is certain to get confused about the difference between:

   return [lambda x, i=i : i * x for i in range(5)]
and

   return [lambda x : i * x for i in range(5)]

Re: Common Python Mistakes

#13
post #9
post #6

Earlier quoted context omitted.

The default value is an expression which is executed when the module is instantiated, even if the expression results in an empty list. If I had: def f(now=datetime.datetime.now()): ... now would be the time when the module was loaded, not when f is called the first time, or when f is called after that, despite datetime objects being immutable.

import datetime, time def foo2(): def foo(a=datetime.datetime.now()): time.sleep(1) return a return foo() for n in range(10): print foo2() 2014-05-08 11:23:01.642871 2014-05-08 11:23:02.644276 2014-05-08 11:23:03.644579 2014-05-08 11:23:04.645146 2014-05-08 11:23:05.646328 2014-05-08 11:23:06.647572 2014-05-08 11:23:07.647904 2014-05-08 11:23:08.648213 2014-05-08 11:23:09.648973 2014-05-08 11:23:10.649742 So, not qui…

You are technically correct, the best type of correct. The top level function is evaluated at module load time.

Re: Common Python Mistakes

#14

> "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…

That's right, in most Python implementations there's a "compiled" part (generally to bytecode) and then an "interpreted" one to run that bytecode. PyPy is a good example of a Python interpreter built on top of RPython (compiled with RPython, that is) adding a JIT to it.

Re: Common Python Mistakes

#15
I've always thought that #1 is a sign of an incorrect operation altogether. If you want to always modify the passed parameter, it doesn't make sense to have a default. If you want to return a modified version of the input, you should make a copy immediately and then you don't get this problem. Doing both an in-place modification and returning a modified object at the same time is just wrong.

Re: Common Python Mistakes

#17

#6 is really confusing. Whenever I encounter something like this my first reaction is that whenever possible such obscure components of a language should be avoided and more verbose/clear code used instead. Programming languages are meant to be read as well as written, and someone relatively new to Python (and many who have used the language for a long time) is certain to get confused about the difference between: re…

Agreed 100%, this type of constructions should be avoided in the first place in favor of more "readable" ones but this happens in a fair amount of code that I've seen (and I keep seeing).

Re: Common Python Mistakes

#18

> "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…

The compiled vs. interpreted thing is kind of a historical relic that people still cling on to. It's not dissimilar to where one draws the line for "scripting" or "nth generation" languages; it's all somewhat nebulously defined.

Re: Common Python Mistakes

#19
post #9
post #6

Earlier quoted context omitted.

The default value is an expression which is executed when the module is instantiated, even if the expression results in an empty list. If I had: def f(now=datetime.datetime.now()): ... now would be the time when the module was loaded, not when f is called the first time, or when f is called after that, despite datetime objects being immutable.

import datetime, time def foo2(): def foo(a=datetime.datetime.now()): time.sleep(1) return a return foo() for n in range(10): print foo2() 2014-05-08 11:23:01.642871 2014-05-08 11:23:02.644276 2014-05-08 11:23:03.644579 2014-05-08 11:23:04.645146 2014-05-08 11:23:05.646328 2014-05-08 11:23:06.647572 2014-05-08 11:23:07.647904 2014-05-08 11:23:08.648213 2014-05-08 11:23:09.648973 2014-05-08 11:23:10.649742 So, not qui…

Kilink's comment apply again.

If you define several functions at different times, the default argument will be evaluated each time you define a new function. You'll have the same behaviour if you keep reassigning lambdas at the same function name, or if you keep edditing the globals.

You are misunderstanding how dynamic Python is. And, yes, the part about "module load time" was a simplification.

Re: Common Python Mistakes

#20
post #7
post #6

Earlier quoted context omitted.

The default value is an expression which is executed when the module is instantiated, even if the expression results in an empty list. If I had: def f(now=datetime.datetime.now()): ... now would be the time when the module was loaded, not when f is called the first time, or when f is called after that, despite datetime objects being immutable.

Isn't that just now being bound to a different datetime object each time f is defined?

Right, it's (re) defined every time you call 'foo2' but that's a different scenario than the one written in the article (hadn't you had 'foo2' and only 'foo' then you'd have the same time in all your calls to the function without supplying arguments).
Post reply on HN