programacion otra orientada objetos metodo llamar lista instancias importar ejemplo clases clase python oop class object expandoobject

otra - programacion orientada a objetos python pdf



Cómo crear un nuevo objeto desconocido o dinámico/expando en Python (5)

Si adopta el enfoque de metaclases de la respuesta de @Martijn, la respuesta de @Ned se puede volver a escribir más corta (aunque obviamente es menos legible, pero hace lo mismo).

obj = type(''Expando'', (object,), {})() obj.foo = 71 obj.bar = ''World''

O simplemente, que hace lo mismo que arriba usando el argumento dict :

obj = type(''Expando'', (object,), {''foo'': 71, ''bar'': ''World''})()

Para Python 3, no es necesario pasar el objeto al argumento de bases (consulte la documentación de type ).

Pero para casos simples, la creación de instancias no tiene ningún beneficio, por lo que está bien:

ns = type(''Expando'', (object,), {''foo'': 71, ''bar'': ''World''})

Al mismo tiempo, personalmente prefiero una clase simple (es decir, sin creación de instancias) para los casos de configuración de prueba ad-hoc como más simple y legible:

class ns: foo = 71 bar = ''World''

Actualizar

En Python 3.3+ hay exactamente lo que pide OP, types.SimpleNamespace . Es solo

Una subclase de object simple que proporciona acceso de atributo a su espacio de nombres, así como una reproducción significativa.

A diferencia del object , con SimpleNamespace puedes agregar y eliminar atributos. Si un objeto SimpleNamespace se inicializa con argumentos de palabras clave, se agregan directamente al espacio de nombres subyacente.

import types obj = types.SimpleNamespace() obj.a = 123 print(obj.a) # 123 print(repr(obj)) # namespace(a=123)

Sin embargo, en stdlib de Python 2 y Python 3 hay argparse.Namespace , que tiene el mismo propósito:

Objeto simple para almacenar atributos.

Implementa la igualdad por nombres de atributos y valores, y proporciona una representación de cadena simple.

import argparse obj = argparse.Namespace() obj.a = 123 print(obj.a) # 123 print(repr(obj)) # Namespace(a=123)

Tenga en cuenta que ambos pueden inicializarse con argumentos de palabras clave:

types.SimpleNamespace(a = ''foo'',b = 123) argparse.Namespace(a = ''foo'',b = 123)

En Python, ¿cómo podemos crear un nuevo objeto sin tener una clase predefinida y luego agregarle propiedades dinámicamente?

ejemplo:

dynamic_object = Dynamic() dynamic_object.dynamic_property_a = "abc" dynamic_object.dynamic_property_b = "abcdefg"

¿Cuál es la mejor manera de hacerlo?

EDITAR Debido a que muchas personas comentaron en los comentarios que no podría necesitar esto.

La cosa es que tengo una función que serializa las propiedades de un objeto. Por esa razón, no quiero crear un objeto de la clase esperada debido a algunas restricciones de los constructores, sino crear uno similar, digamos como un simulacro , agregar las propiedades "personalizadas" que necesito, luego enviarlas a la función.


Solo define tu propia clase para hacerlo:

class Expando(object): pass ex = Expando() ex.foo = 17 ex.bar = "Hello"


Una forma que encontré es también creando un lambda. Puede tener efectos secundarios y viene con algunas propiedades que no se desean. Sólo publicar para el interés.

dynamic_object = lambda:expando dynamic_object.dynamic_property_a = "abc" dynamic_object.dynamic_property_b = "abcdefg"


Usar un objeto solo para mantener valores no es el estilo de programación más Pythonic. Es común en los lenguajes de programación que no tienen buenos contenedores asociativos, pero en Python, puedes usar un diccionario:

my_dict = {} # empty dict instance my_dict["foo"] = "bar" my_dict["num"] = 42

También puede usar un "diccionario literal" para definir todos los contenidos del diccionario a la vez:

my_dict = {"foo":"bar", "num":42}

O, si sus claves son todas identificadoras legales (y lo serán, si planeaba que fueran nombres de atributos), puede usar el constructor dict con argumentos de palabras clave como pares clave-valor:

my_dict = dict(foo="bar", num=42) # note, no quotation marks needed around keys

De hecho, completar un diccionario es lo que Python está haciendo entre bambalinas cuando usas un objeto, como en la respuesta de Ned Batchelder. Los atributos de su ex objeto se almacenan en un diccionario, ex.__dict__ , que debería terminar siendo igual a un dict equivalente creado directamente.

A menos que la sintaxis de atributos (por ejemplo, ex.foo ) sea absolutamente necesaria, también puede omitir el objeto por completo y usar un diccionario directamente.


Use la fábrica de clases collections.namedtuple() para crear una clase personalizada para su valor de retorno:

from collections import namedtuple return namedtuple(''Expando'', (''dynamic_property_a'', ''dynamic_property_b''))(''abc'', ''abcdefg'')

El valor devuelto se puede utilizar tanto como tupla como por acceso de atributo:

print retval[0] # prints ''abc'' print retval.dynamic_property_b # prints ''abcdefg''