Wat/Gotcha: casos extremos y contraituitivos
Deberíamos juzgar un lenguaje por sus gotchas?
>>> False == (False in [False])
... False
>>> (False == False) in [False]
... False
>>> False == False in [False]
... ?
>>> False == (False in [False])
... False
>>> (False == False) in [False]
... False
>>> False == False in [False]
... True
>>> False == False in [False]
True
- `in` es un operador logico
- Todos los operadores lógicos tiene la misma precedencia
- Las operaciones del tipo 1<a<3 se evaluan como 1<a and a<2
>>> False == False and False in [False]
True
>>> data = {
... 1: 'one',
... '1': 'two',
... True: 'true',
... }
>>> data
?
>>> data = {
... 1: 'one',
... '1': 'two',
... True: 'true',
... }
>>> data
{1: 'true', '1': 'two'}
"The Boolean type is a subtype of the integer type, and Boolean values behave like the values 0 and 1"
>>> a = 256
>>> b = 256
>>> a is b
True
>>> a = 257
>>> b = 257
>>> a is b
False
>>> a = 257
>>> b = 257
>>> a is b
False
>>> a = 257; b = 257
>>> a is b
?
>>> a = 257
>>> b = 257
>>> a is b
False
>>> a = 257; b = 257
>>> a is b
True
>>> code_obj_a = compile (source="a = 257", filename="", mode="exec")
>>> code_obj_a.co_consts
(257,None)
>>> code_obj_a = compile (source="a = 257; b = 257", filename="", mode="exec")
>>> code_obj_a.co_consts
(257,None)
# ver:
http://www.laurentluce.com/posts/python-integer-objects-implementation/
>>> def foo(l=[]):
... l.append('cat')
... return l
>>> foo()
['cat']
>>> foo()
['cat', 'cat']
# Parece que l=[] se ejectua sólo una vez (cuando definimos la función).
# Si es así entonces...
>> def bar(l=[]):
... print (locals())
... l = ['cat']
... return l
...
>>> bar()
# ? {'l': []}
# ? ['cat']
>>> bar()
# ? {'l': ['cat']}
# ? ['cat']
>>> def bar(l=[]):
... print (locals())
... l = ['cat']
... return l
...
>>> bar()
{'l': []}
['cat']
>>> bar()
{'l': []}
['cat']
>>> def foo(l=[]):
... l.append('cat')
... return l
...
>>> foo.__defaults__ # foo.func_defaults en Py 2
(['cat'],)
>>> foo.__defaults__[0].append('dragon')
>>> foo.__defaults__
(['cat', 'dragon'],)
>>> foo()
['cat', 'dragon', 'cat']
>>> def bar(l=[]):
... print locals()
... l = ['cat']
... return l
>>> bar.__defaults__
([],)
>>> bar()
{'l': []} ## locals
['cat']
>>> bar.__defaults__
([],)
# Al reasignar 'l' a otra lista, no se modifica la lista contenida en __defaults__
# por eso funciona lo siguiente:
def append_to(element, to=None):
if to is None:
to = []
to.append(element)
return to
class AAA(object):
x = 1
class BBB(AAA):
pass
class CCC(AAA):
pass
>>> print AAA.x, BBB.x, CCC.x
?
>>> BBB.x = 2
>>> print AAA.x, BBB.x, CCC.x
?
>>> AAA.x = 3
>>> print AAA.x, BBB.x, CCC.x
?
class AAA(object):
x = 1
class BBB(AAA):
pass
class CCC(AAA):
pass
# AAA: {'x': 1}, BBB: {}, CCC: {}
>>> print AAA.x, BBB.x, CCC.x
1 1 1
>>> BBB.x = 2
# AAA: {'x': 1}, BBB: {'x': 2}, CCC: {}
>>> print AAA.x, BBB.x, CCC.x
1 2 1
>>> AAA.x = 3
# AAA: {'x': 3}, BBB: {'x': 2}, CCC: {}
>>> print AAA.x, BBB.x, CCC.x
3 2 3
>>> a = ([42],)
>>> a[0] += [43, 44]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'tuple' object does not support item assignment
>>> a = ([42],)
>>> a[0] += [43, 44]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'tuple' object does not support item assignment
>>> a
([42, 43, 44],)
>>> a = ([42],)
>>> a[0] += [43, 44]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'tuple' object does not support item assignment
>>> a
([42, 43, 44],)
>>> a = ([42],)
>>> b = a[0]
>>> b += [43, 44]
>>> a
([42, 43, 44],)
>>> all([])
True
>>> all([])
True
>>> all([[]])
False
>>> all([])
True
>>> all([[]])
False
>>> all([[[]]])
True
>>> all([]) ## por definicion de la funcion
True
>>> all([[]])
False
>>> all([[[]]])
True
>>> all([]) ## por definicion de la funcion
True
>>> all([[]]) ## bool([]) -> False
False
>>> all([[[]]])
True
>>> all([]) ## por definicion de la funcion
True
>>> all([[]]) ## [[]] -> [False]
False
>>> all([[[]]])
True
>>> all([]) ## por definicion de la funcion
True
>>> all([[]]) ## [[]] -> [False]
False
>>> all([[[]]]) ## bool ( [False]) -> True
True
>>> all([]) ## por definicion de la funcion
True
>>> all([[]]) ## [[]] -> [False]
False
>>> all([[[]]]) ## [[[]]] -> [[False]] -> [True]
True
>>> x = float("nan")
>>> len({x, x, float(x), float(x), float("nan"), float("nan")})
?
>>> len({x, float(x), float("nan")})
?
>>> x = float("nan")
>>> len({x, x, float(x), float(x), float("nan"), float("nan")})
3
>>> len({x, float(x), float("nan")})
2
>>> x = float("nan")
>>> {x, x, float(x), float(x), float("nan"), float("nan")}
set([nan, nan, nan])
>>> {x, float(x), float("nan")}
set([nan, nan])
>>> x is x
True
>>> float(x)==float(x)
True
>>> float(x)==x
True
>>> float("nan") == float("nan")
False
>>> a = 2, 1, 3
>>> sorted(a) == sorted(a)
?
>>> reversed(a) == reversed(a)
?
>>> a = 2, 1, 3
>>> sorted(a) == sorted(a)
True
>>> reversed(a) == reversed(a)
False
>>> isinstance (type, object)
>>> ?
>>> isinstance (object, type)
>>> ?
>>> isinstance (type, object)
>>> true
>>> isinstance (object, type)
>>> true
http://stackoverflow.com/questions/530530/python-2-x-gotchas-and-landmines
https://www.youtube.com/watch?v=sH4XF6pKKmk
https://github.com/cosmologicon/pywat
https://docs.python.org/3/faq/programming.html#why-does-a-tuple-i-item-raise-an-exception-when-the-addition-works