http://makina-corpus.com
>>> def func(things=[]):
... things.append("PyConFr")
... return things
...
>>> func()
???
>>> def func(things=[]):
... things.append("PyConFr")
... return things
...
>>> func()
['PyConFr']
>>> func()
???
>>> def func(things=[]):
... things.append("PyConFr")
... return things
...
>>> func()
['PyConFr']
>>> func()
['PyConFr', 'PyConFr']
>>> func()
['PyConFr', 'PyConFr', 'PyConFr']
>>> func.__defaults__
(['PyConFr', 'PyConFr', 'PyConFr'],)
>>> func.__defaults__
(['PyConFr', 'PyConFr', 'PyConFr'],)
>>> del func.__defaults__[0][:]
>>> func.__defaults__
([],)
>>> func()
['PyConFr']
>>> func.__defaults__[0].append(
... 'Django Carrots')
>>> func()
['PyConFr', 'Django Carrots', 'PyConFr']
>>> def func(things=[]):
... print(id(things))
... things.append("PyConFr")
... return things
...
>>> func()
140014883158640
['PyConFr']
>>> func()
140014883158640
['PyConFr', 'PyConFr']
>>> func()
140014883158640
['PyConFr', 'PyConFr', 'PyConFr']
Python Programming FAQ:
>>> functions = []
>>> for i in range(5):
... def func():
... return i
... functions.append(func)
...
>>> for func in functions:
... func()
...
?
?
?
?
?
>>> functions = []
>>> for i in range(5):
... def func():
... return i
... functions.append(func)
...
>>> for func in functions:
... func()
...
4
4
4
4
4
>>> from dis import dis
>>> dis(functions[0])
3 0 LOAD_GLOBAL 0 (i)
3 RETURN_VALUE
>>> dis(functions[4])
3 0 LOAD_GLOBAL 0 (i)
3 RETURN_VALUE
Doc du module dis:
LOAD_GLOBAL(namei)
Loads the global named co_names[namei] onto the stack.
>>> functions = []
>>> for i in range(5):
... def func(i=i):
... return i
... functions.append(func)
...
>>> for func in functions:
... func()
...
0
1
2
3
4
>>> dis(functions[0])
3 0 LOAD_FAST 0 (i)
3 RETURN_VALUE
>>> dis(functions[4])
3 0 LOAD_FAST 0 (i)
3 RETURN_VALUE
Doc du module dis:
LOAD_FAST(var_num)
Pushes a reference to the local co_varnames[var_num] onto the stack.
Python Programming FAQ:
Why do lambdas defined in a loop with different values all return the same result?
>>> x = 10
>>> def bar():
... print(x)
>>> bar()
??
>>> x = 10
>>> def bar():
... print(x)
>>> bar()
10
>>> x = 10
>>> def foo():
... print(x)
... x += 1
...
>>> foo()
??
>>> x = 10
>>> def foo():
... print(x)
... x += 1
...
>>> foo()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 2, in foo
UnboundLocalError: local variable 'x' referenced before assignment
>>> def bar():
... print(x)
...
>>> dis(bar)
2 0 LOAD_GLOBAL 0 (x)
3 PRINT_ITEM
4 PRINT_NEWLINE
5 LOAD_CONST 0 (None)
8 RETURN_VALUE
>>> def foo():
... print(x)
... x += 1
...
>>> dis(foo)
2 0 LOAD_FAST 0 (x)
3 PRINT_ITEM
4 PRINT_NEWLINE
3 5 LOAD_FAST 0 (x)
8 LOAD_CONST 1 (1)
11 INPLACE_ADD
12 STORE_FAST 0 (x)
15 LOAD_CONST 0 (None)
18 RETURN_VALUE
Python Programming FAQ: Why am I getting an UnboundLocalError when the variable has a value?
when you make an assignment to a variable in a scope, that variable becomes local to that scope and shadows any similarly named variable in the outer scope
>>> x = 10
>>> def foo():
... global x
... print(x)
... x += 1
...
>>> foo()
10
>>> a = 256
>>> b = 256
>>> a is b
???
>>> a = 256
>>> b = 256
>>> a is b
True
>>> a = 257
>>> b = 257
>>> a is b
???
>>> a = 257
>>> b = 257
>>> a is b
False
https://docs.python.org/2/c-api/int.html
The current implementation keeps an array of integer objects for all integers between -5 and 256, when you create an int in that range you actually just get back a reference to the existing object.
Object identity of primitive values works by value equality, not by identity of the wrapper. This means that x + 1 is x + 1 is always true, for arbitrary integers x
>>> a = 257; b = 257;
>>> a is b
???
>>> a = 257; b = 257;
>>> a is b
True
>>> a = 257
>>> b = 257
est équivalent à :
>>> code1 = compile("a = 257", filename="",
... mode="exec")
>>> code2 = compile("b = 257", filename="",
... mode="exec")
>>> code1.co_consts
(257, None)
>>> code2.co_consts
(257, None)
>>> code1.co_consts[0] is code2.co_consts[0]
False
>>> a = 257; b = 257;
>>> a is b
est équivalent à :
>>> code = compile("a = 257; b = 257",
filename="", mode="exec")
>>> code.co_consts
(257, None)
>>> "100" > 1
???
>>> "100" > 1
True
>>> "100" > 1000
???
>>> "100" > 1000
True
>>> [1000] > [500]
???
>>> [1000] > [500]
True
>>> [1000] > (500, )
???
>>> [1000] > (500, )
False
Objects of different types except numbers are ordered by their type names
>>> type([1000]).__name__
'list'
>>> type((500, )).__name__
'tuple'
>>> 'list' > 'tuple'
False
>>> [1000] > (500, )
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unorderable types: list() > tuple()
>>> "100" > 1000
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unorderable types: str() > int()
Une présentation en anglais de Amy Hanlon : Investigating Python Wats
| Pièges et bizarreries de (C)Python | 1 |
|---|---|
| Makina Corpus | 2 |
| - | 3 |
| - | 4 |
| - | 5 |
| - | 6 |
| - | 7 |
| - | 8 |
| - | 9 |
| - | 10 |
| - | 11 |
| - | 12 |
| - | 13 |
| - | 14 |
| - | 15 |
| - | 16 |
| - | 17 |
| - | 18 |
| - | 19 |
| - | 20 |
| - | 21 |
| - | 22 |
| - | 23 |
| - | 24 |
| - | 25 |
| - | 26 |
| - | 27 |
| CPython | 28 |
| PyPy | 29 |
| - | 30 |
| - | 31 |
| - | 32 |
| - | 33 |
| - | 34 |
| - | 35 |
| - | 36 |
| - | 37 |
| - | 38 |
| - | 39 |
| - | 40 |
| - | 41 |
| - | 42 |
| - | 43 |
| Python 3 | 44 |
| Inspiration | 45 |
| Table of contents | t |
|---|---|
| Exposé | ESC |
| Autoscale | e |
| Full screen slides | f |
| Presenter view | p |
| Source files | s |
| Slide numbers | n |
| Blank screen | b |
| Notes | 2 |
| Help | h |