3 ms·
It's incredibly confusing if you naively use a list as a default argument, e.g. def foo(some_list=[]): ... some_list.append(3) ...
by ben509 7y ago
It's incredibly confusing if you naively use a list as a default argument, e.g.
def foo(some_list=[]):
...
some_list.append(3)
...
Since the default is constructed when the function is evaluated, it's the same list, but only when the default is used.
Or the n00b's attempt to use lambdas:
def list_of_lambdas(x):
result = []
for n in range(x):
result.append(lambda m: n + m)
return result
for func in list_of_lambdas(3):
print(func(3))
5
5
5
(All the closures share the same "cell", meaning the same "n", which is 2 at the end of that loop. Worse, if you 'yield lambda ...', that example would look like it worked. So, yes, Python absolutely has references.)
- jlokier 7y agoYes indeed, that's a bug-prone misfeature of Python. Perl and JavaScript both get default arguments right: They make a new array on each call. Perl and JavaScript also get the for-loop closures right as well. In Perl, "for (my $n = ...)" and in JavaScript "for (let n = ...)" will both create a new "cell" each time around the loop, so closures work as expected. (However, MSIE's version of "let" doesn't create a new "cell" each time, and this can be a source of difficult to see event callback bugs; best transpiled out.)
- zbentley 7y agoPerl has default arguments (outside of Devel::Declare trickery)?
- jlokier 7y agoYes, built-in since Perl 5.20, released mid 2014. use experimental qw(signatures); sub plus_one($x = 100) { return $x + 1; } # Says 6. say plus_one(5); # Says 101. say plus_one(); (The subroutine signatures feature is still marked experimental, which is a shame. I use it in virtually all my code, unless I want pre-5.20 compatibility.)
- zbentley 7y agoNeat, thanks! I can't use it unfortunately (the little Perl I still write targets 5.8 on ancient CentOS, but that's not the language's fault). Good to see it still evolving!