python pycharm warnings

python - Advertencia sobre el argumento predeterminado mutable en PyCharm



warnings (3)

Para reformular la advertencia: cada llamada a esta función, si usa el valor predeterminado, usará el mismo valor. Siempre que nunca cambies ese valor, el hecho de que sea mutable no importará. Pero si lo cambia, las llamadas posteriores comenzarán con el valor modificado , que probablemente no sea lo que desea.

Una solución para evitar este problema sería hacer que el valor predeterminado sea un valor inmutable y establecer el parámetro en {} si se usa ese valor predeterminado:

def put_wall_post(self,message,attachment=None,profile_id="me"): if attachment==None: attachment={} return self.put_object(profile_id,"feed",message = message,**attachment)

Estoy usando PyCharm (Python 3) para escribir una función de Python que acepta un diccionario como argumento con el attachment={} .

def put_object(self, parent_object, connection_name, **data): ... def put_wall_post(self, message, attachment={}, profile_id="me"): return self.put_object(profile_id, "feed", message=message, **attachment)

En el IDE, el attachment={} es de color amarillo. Mover el mouse sobre él muestra una advertencia.

El valor predeterminado de los argumentos es mutable

Esta inspección detecta cuándo se detecta un valor mutable como lista o diccionario en un valor predeterminado para un argumento.

Los valores de los argumentos predeterminados se evalúan solo una vez en el tiempo de definición de la función, lo que significa que la modificación del valor predeterminado del argumento afectará a todas las llamadas posteriores de la función.

¿Qué significa esto y cómo puedo resolverlo?


Puede reemplazar los argumentos predeterminados mutables con None . A continuación, compruebe dentro de la función y asigne el valor predeterminado:

def put_wall_post(self, message, attachment=None, profile_id="me"): attachment = attachment if attachment else {} return self.put_object(profile_id, "feed", message=message, **attachment)

Esto funciona porque None evalúa como False por lo que luego asignamos un diccionario vacío.

En general, es posible que desee verificar explícitamente la opción None ya que otros valores también podrían evaluar a False , por ejemplo, 0 , '''' , set() , [] , etc., son todos False-y . Si su valor predeterminado no es 0 y es 5 por ejemplo, no querría pisar el paso de 0 como parámetro válido:

def function(param=None): param = 5 if param is None else param


Si no altera el "argumento predeterminado mutable" o lo pasa a cualquier lugar donde pueda modificarse, simplemente ignore el mensaje, porque no hay nada que "arreglar".

En su caso, solo desempaqueta (lo que hace una copia implícita) el "argumento predeterminado mutable", por lo que está seguro.

Si desea "eliminar ese mensaje de advertencia", podría usar None como predeterminado y configurarlo en {} cuando no sea None :

def put_wall_post(self,message,attachment=None,profile_id="me"): if attachment is None: attachment = {} return self.put_object(profile_id,"feed",message = message,**attachment)

Solo para explicar "lo que significa": algunos tipos en Python son inmutables ( int , str , ...) otros son mutables (como dict , set , list , ...). Si desea cambiar objetos inmutables, se crea otro objeto, pero si cambia objetos mutables, el objeto sigue siendo el mismo pero su contenido se modifica.

La parte difícil es que las variables de clase y los argumentos predeterminados se crean cuando se carga la función (y solo una vez), eso significa que cualquier cambio en un "argumento predeterminado mutable" o "variable de clase mutable" son permanentes:

def func(key, value, a={}): a[key] = value return a >>> print(func(''a'', 10)) # that''s expected {''a'': 10} >>> print(func(''b'', 20)) # that could be unexpected {''b'': 20, ''a'': 10}

PyCharm probablemente muestre esta Advertencia porque es fácil equivocarse por accidente (ver, por ejemplo, "El menor asombro" y el Argumento predeterminado mutable y todas las preguntas relacionadas). Sin embargo, si lo hizo a propósito (¿ buenos usos para los valores predeterminados de argumentos de función mutables? ) La Advertencia podría ser molesta.