Hola usuario de nuestra web, hemos encontrado la respuesta a lo que andabas buscando, has scroll y la verás más abajo.
Solución:
Esto parece un truco para crear un objeto simple para contener valores en una línea. La mayoría de los objetos incorporados no le permiten establecer arbitrariamente attributes en ellos:
>>> object().x = 0
Traceback (most recent call last):
File "", line 1, in
AttributeError: 'object' object has no attribute 'x'
>>> ''.x = 0
Traceback (most recent call last):
File "", line 1, in
AttributeError: 'str' object has no attribute 'x'
>>> [].x = 0
Traceback (most recent call last):
File "", line 1, in
AttributeError: 'list' object has no attribute 'x'
Si haces tu propia clase, entonces puedes agregar lo que sea attributes usted quiere. En este caso podrías hacer una clase cuya __init__
método asigna el attributes, pero esto puede no valer la pena. Entonces puedes hacer una clase vacía:
>>> class Data(object): pass
>>> d = Data()
>>> d.x = 0
>>> d.x
0
Aparentemente, el programador no es consciente de esto o no quiere esa línea adicional donde se declara la clase y ha encontrado su propia solución para almacenar datos. Resulta funcional, a pesar de ser de tipo incorporado hacer te permite agregar attributes a ellos:
>>> def foo(): pass
>>> foo.x = 0
>>> foo.x
0
Tanto lo anterior como una lambda le permiten crear dicho contenedor en una sola declaración. De hecho, creo que es una buena idea.
¿Cuál es la ventaja de usar una función lambda:None?
Que está pasando aqui
eris = lambda:None
eris.jkcpp = ...
es que el escritor está usando el espacio de nombres (el __dict__
) de un objeto función.
Esto es muy poco común. yo lo evitaria
un espacio de nombres es un dominio donde los nombres legales de Python se asignan a objetos, y cuando hace algo como lo anterior, la ventaja de un espacio de nombres es que los nombres no están en el ámbito local y global donde podrían sobrescribir o ser sobrescrito donde los mismos nombres apuntan a diferentes objetos.
No hay nada de malo en esto a primera vista, pero si otros están tratando de leer el código para entender qué está pasando con esta función que se está pasando, entonces probablemente estén pensando:
¿Alguna vez se llamará a la lambda? ¿Por qué estamos pasando un invocable? Un invocable que devuelve Ninguno no es muy útil, debe ser algún tipo de pirateo.
Para evitar confusiones, utilice un objeto que se entenderá semánticamente como un espacio de nombres.
Espacios de nombres
Tenemos un objeto SimpleNamespace en la biblioteca estándar de Python 3:
from types import SimpleNamespace
eris = SimpleNamespace()
eris.jkcpp = ...
En Python 2, sería común hacer algo como:
class NS(object):
pass
eris = NS()
eris.jkcpp = ...
Si necesita un espacio de nombres simple, estas son buenas opciones.
Desventajas
Sin embargo, todavía tengo que ver mucho uso de estas formas de espacios de nombres. Encuentro que una tupla con nombre sería suficiente cuando quiero que la semántica se transmita con los datos (particularmente útil cuando hay muchos de ellos) o uso un objeto mutable con más que solo pass
en eso.
Tal como son, en realidad no son diferentes, programáticamente, de un diccionario simple. Los valores a los que apuntan los nombres se almacenan en el objeto __dict__
. También puede estar pasando alrededor de un dict
ejemplo. La búsqueda punteada también agrega un poco de sobrecarga (se verifica para ver si el tipo de objeto tiene descriptores de datos antes de buscar en el diccionario del objeto).
Conclusión:
La instancia del espacio de nombres puede tener algunas desventajas, pero puede ser más legible. La legibilidad cuenta. Si cree que su programa necesita un espacio de nombres simple, utilícelo.
Pero no utilice una función de no hacer nada para un espacio de nombres. Es engañoso y no tendrá sentido para nadie.