No muchos conocen esta característica, pero las funciones (y métodos) de Python pueden tener atributos . Mirad:
>>> def foo(x):
... pass
...
>>> foo.score = 10
>>> dir(foo)
['__call__', '__class__', '__delattr__', '__dict__', '__doc__', '__get__', '__getattribute__', '__hash__', '__init__', '__module__', '__name__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__str__', 'func_closure', 'func_code', 'func_defaults', 'func_dict', 'func_doc', 'func_globals', 'func_name', 'score']
>>> foo.score
10
>>> foo.score += 1
>>> foo.score
11
¿Cuáles son los posibles usos y abusos de esta función en Python? Un buen uso que conozco es el uso que hace PLY de la cadena de documentación para asociar una regla de sintaxis con un método. ¿Pero qué pasa con los atributos personalizados? ¿Hay buenas razones para usarlos?
python
function
attributes
Eli Bendersky
fuente
fuente
Respuestas:
Normalmente uso atributos de funciones como almacenamiento para anotaciones. Supongamos que quiero escribir, al estilo de C # (lo que indica que cierto método debería ser parte de la interfaz del servicio web)
entonces puedo definir
Luego, cuando llega una llamada de servicio web, busco el método, compruebo si la función subyacente tiene el atributo is_webmethod (el valor real es irrelevante) y rechazo el servicio si el método está ausente o no se debe llamar a través de la web.
fuente
.__doc__
Los he usado como variables estáticas para una función. Por ejemplo, dado el siguiente código C:
Puedo implementar la función de manera similar en Python:
Esto definitivamente caería en el extremo de "abusos" del espectro.
fuente
Puede hacer objetos a la manera de JavaScript ... No tiene sentido pero funciona;)
fuente
def test()
realmente necesario?Los uso con moderación, pero pueden ser bastante convenientes:
Ahora puedo usar
log
todo mi módulo y redirigir la salida simplemente configurandolog.logfile
. Hay muchas otras formas de lograrlo, pero este es liviano y muy simple. Y aunque olía raro la primera vez que lo hice, he llegado a creer que huele mejor que tener unalogfile
variable global .fuente
Los atributos de función se pueden usar para escribir cierres ligeros que envuelvan el código y los datos asociados juntos:
1.00934004784
2.00644397736
3.01593494415
fuente
time.sleep(1)
es mejor queos.system('sleep 1')
He creado este decorador auxiliar para configurar fácilmente los atributos de la función:
Un caso de uso es crear una colección de fábricas y consultar el tipo de datos que pueden crear en un meta nivel de función.
Por ejemplo (muy tonto):
fuente
factory1.datatype=list
justo debajo de la declaración como decoradores de estilo antiguo?items()
lugar deiteritems()
.A veces uso un atributo de una función para almacenar en caché los valores ya calculados. También puede tener un decorador genérico que generalice este enfoque. ¡Tenga en cuenta los problemas de concurrencia y los efectos secundarios de tales funciones!
fuente
Siempre supuse que la única razón por la que esto era posible era porque había un lugar lógico para colocar una cadena de documentos u otras cosas similares. Sé que si lo usara para algún código de producción, confundiría a la mayoría de los que lo leen.
fuente