On Github xurxof / pygotchas
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