referencias confuso para el mismo objeto (mutable) con referencias a objetos separados es de hecho un " gotcha "(padecido por todos los lenguajes no funcionales, que tienen objetos mutables y, por supuesto, referencias). Un error frecuente en el código Python para principiantes está haciendo mal uso de un valor predeterminado que es mutable, por ejemplo:
def addone(item, alist=[]):
alist.append(item)
return alist
Este código puede ser correcto si el propósito es tener addone
mantener su propio estado (y devuelve la lista de un crecimiento a las personas que llaman sucesivamente), al igual que static
datos trabajarían en C; no es correcto si el codificador está asumiendo erróneamente que se hará una nueva lista vacía en cada llamada.
principiantes primas utilizadas para los lenguajes funcionales también pueden ser confundidos por la decisión command-query separation diseño en incorporadas en recipientes de Python: métodos de mutación que no tienen nada en particular para volver (es decir, la gran mayoría de mutar métodos) no regresar (específicamente, devuelven None
) - están haciendo todo su trabajo "en el lugar". Los errores que provienen de malentendidos son fáciles de detectar, p.
alist = alist.append(item)
es más o menos garantiza que sea un error - que añade un elemento a la lista mencionada por su nombre alist
, pero luego vuelve a vincular el nombre alist
a None
(el valor de retorno de la llamada append
).
Si bien el primer problema que mencioné es acerca de una vinculación temprana que puede engañar a las personas que piensan que la vinculación es tardía, hay problemas que van en la dirección opuesta, donde las expectativas de algunas personas son de una vinculación temprana mientras que el enlace es, en cambio, tarde. Por ejemplo (con un marco hipotético interfaz gráfica de usuario ...):
for i in range(10):
Button(text="Button #%s" % i,
click=lambda: say("I'm #%s!" % i))
esto mostrará diez botones diciendo "Botón # 0", "Botón # 1", etc., pero, al hacer clic, todos y cada uno de ellos serán say
es #9
- porque el i
dentro del lambda
está atrasado (con un cierre léxico). Una solución es tomar ventaja del hecho de que los valores por defecto de argumento son-principios determinada (como he señalado sobre el primer número! -) y cambiar la última línea de
click=lambda i=i: say("I'm #%s!" % i))
Ahora lambda
's i
es un argumento con un valor predeterminado, no una variable libre (consultada por cierre léxico), por lo que el código funciona según lo previsto (también existen otras formas, por supuesto).
Esa fue la principal Gotcha para mí en cambio a Python, pero creo que también es una Gotcha común que las personas que comienzan a utilizar Python sin haber utilizado Matlab antes. Sin embargo, podría estar equivocado. –
Relacionados: http://zephyrfalcon.org/labs/python_pitfalls.html http://www.ferg.org/projects/python_gotchas.html – jfs