variable type defines define data create constant python object-literal

type - python create constant



¿Los literales de objeto son pitónicos? (7)

JavaScript tiene literales de objeto, por ejemplo

var p = { name: "John Smith", age: 23 }

y .NET tiene tipos anónimos, por ejemplo

var p = new { Name = "John Smith", Age = 23}; // C#

Algo similar se puede emular en Python mediante (ab) usando argumentos con nombre:

class literal(object): def __init__(self, **kwargs): for (k,v) in kwargs.iteritems(): self.__setattr__(k, v) def __repr__(self): return ''literal(%s)'' % '', ''.join(''%s = %r'' % i for i in sorted(self.__dict__.iteritems())) def __str__(self): return repr(self)

Uso:

p = literal(name = "John Smith", age = 23) print p # prints: literal(age = 23, name = ''John Smith'') print p.name # prints: John Smith

Pero, ¿se considera que este tipo de código es pitónico?


¿Has considerado usar una tupla nombrada ?

Usando tu notación dict

>>> from collections import namedtuple >>> L = namedtuple(''literal'', ''name age'')(**{''name'': ''John Smith'', ''age'': 23})

o argumentos de palabra clave

>>> L = namedtuple(''literal'', ''name age'')(name=''John Smith'', age=23) >>> L literal(name=''John Smith'', age=23) >>> L.name ''John Smith'' >>> L.age 23

Es posible ajustar este comportamiento en una función con la suficiente facilidad

def literal(**kw): return namedtuple(''literal'', kw)(**kw)

el equivalente lambda sería

literal = lambda **kw: namedtuple(''literal'', kw)(**kw)

pero personalmente creo que es tonto dar nombres a funciones "anónimas"


¿Por qué no usar un diccionario?

p = {''name'': ''John Smith'', ''age'': 23} print p print p[''name''] print p[''age'']


Creo que los literales de objetos tienen sentido en JavaScript por dos razones:

  1. En JavaScript, los objetos son solo una forma de crear una "cosa" con propiedades de índice de cadena. En Python, como se señala en otra respuesta, el tipo de diccionario lo hace.

  2. El sistema de objetos de JavaScript está basado en prototipos. No existe una clase en JavaScript (aunque viene en una versión futura): los objetos tienen objetos prototipo en lugar de clases. Por lo tanto, es natural crear un objeto "de la nada", a través de un literal, porque todos los objetos solo requieren el objeto raíz incorporado como prototipo. En Python, cada objeto tiene una clase: se espera que uses objetos para cosas donde tendrías varias instancias, en lugar de solo para una.

Por lo tanto, no, los literales de objeto no son Pythonic, pero son JavaScripthonic.


Desde ActiveState :

class Bunch: def __init__(self, **kwds): self.__dict__.update(kwds) # that''s it! Now, you can create a Bunch # whenever you want to group a few variables: point = Bunch(datum=y, squared=y*y, coord=x) # and of course you can read/write the named # attributes you just created, add others, del # some of them, etc, etc: if point.squared > threshold: point.isok = 1


Desde el IAQ de Python :

A partir de Python 2.3, puedes usar la sintaxis

dict(a=1, b=2, c=3, dee=4)

que es lo suficientemente bueno en lo que a mí respecta. Antes de Python 2.3 utilicé la función de una línea

def Dict(**dict): return dict


No veo nada de malo en crear clases / instancias "anónimas". A menudo es muy conveniente crear uno con llamada de función simple en una línea de código. Yo personalmente uso algo como esto:

def make_class( *args, **attributes ): """With fixed inability of using ''name'' and ''bases'' attributes ;)""" if len(args) == 2: name, bases = args elif len(args) == 1: name, bases = args[0], (object, ) elif not args: name, bases = "AnonymousClass", (object, ) return type( name, bases, attributes ) obj = make_class( something = "some value" )() print obj.something

Para crear objetos ficticios funciona bien. Namedtuple está bien, pero es inmutable, lo que a veces puede ser un inconveniente. Y el diccionario es ... bueno, un diccionario, pero hay situaciones en las que tiene que pasar algo con __getattr__ definido, en lugar de __getitem__ .

No sé si es pitónico o no, pero a veces acelera las cosas y para mí es razón suficiente para usarlo (a veces).


Un diccionario simple debería ser suficiente para la mayoría de los casos.

Si está buscando una API similar a la que indicó para el caso literal, aún puede usar diccionarios y simplemente anular la función especial __getattr__ :

class CustomDict(dict): def __getattr__(self, name): return self[name] p = CustomDict(user=''James'', location=''Earth'') print p.user print p.location

Nota : Tenga en cuenta que, a diferencia de las tiros con nombre, los campos no están validados y usted está a cargo de asegurarse de que sus argumentos sean correctos. Argumentos como p[''def''] = ''something'' son tolerados dentro de un diccionario, pero no podrá acceder a ellos a través de p.def .