2011-05-08 29 views
42

Necesito crear dinámicamente una instancia de una clase en Python. Básicamente, estoy usando el módulo load_module e inspecciono el módulo para importar y cargar la clase en un objeto de clase, pero no puedo encontrar la manera de crear una instancia de este objeto de clase.Cómo crear una instancia nueva a partir de un objeto de clase en Python

Por favor ayuda!

+5

¿Qué? 'instance = Class()' ... –

+0

Supongo que quieres crear dinámicamente una nueva clase. No es un objeto de una clase dada. – jsbueno

+0

nueva instancia significa un nuevo objeto con su propio espacio en la memoria. la mayoría de los lenguajes usan una palabra clave 'nueva' para que sea explícito que el objeto es nuevo y que las propiedades de la nueva instancia (del objeto) no se referencian/comparten con otra instancia. – BillR

Respuesta

12

Sólo tiene que llamar el "tipo", construida en el uso de tres parámetros, así:

ClassName = type("ClassName", (Base1, Base2,...), classdictionary) 

actualización como se indica en el comentario de abajo esta no es la respuesta a esta pregunta en absoluto. Lo mantendré sin recuperar, ya que hay indicios de que algunas personas llegan aquí tratando de crear clases dinámicamente, que es lo que hace la línea de arriba.

Para crear un objeto de una clase haya una referencia también, como poner en la respuesta aceptada, uno sólo tiene que llamar a la clase:

instance = ClassObject() 

El mecanismo para la creación de instancias es así:

Python no utiliza la palabra clave new que usan algunos idiomas, sino que su modelo de datos explica el mecanismo utilizado para crear un instantance de una clase cuando se llama con la misma sintaxis que cualquier otra llamada:

Su clase 'Se invoca el método(en el caso de una clase, su clase es la "metaclase", que generalmente es la incorporada en type). El comportamiento normal de esta llamada es invocar el método (pseudo) estático __new__ en la clase que se está instanciando, seguido de su __init__. El método __new__ es responsable de asignar memoria y tal, y normalmente lo hace el __new__ de object, que es la jerarquía de clase raíz.

Así llamando ClassObject() invoca ClassObject.__class__.call() (que normalmente será type.__call__) este método __call__ recibirá classObject a sí mismo como el primer parámetro - una implementación de Python puro sería así: (la versión CPython es, por supuesto, hecho en C, y con una gran cantidad de código extra para cornercases y optimizaciones)

class type: 
    ... 
    def __call__(cls, *args, **kw): 
      constructor = getattr(cls, "__new__") 
      instance = constructor(cls) if constructor is object.__new__ else constructor(cls, *args, **kw) 
      instance.__init__(cls, *args, **kw) 
      return instance 

(que no recuerdo haber visto en los documentos de la justificación exacta (o mecanismo) para suprimir parámetros adicionales a la raíz __new__ y pasarlo a otras clases - pero es lo que sucede "en la vida real" - si se llama a object.__new__ con cualquier parámetro adicional ERS plantea un error de tipo - sin embargo, cualquier implementación personalizada de un __new__ obtendrá los parámetros extra normalmente)

+6

¿El OP no quería crear una instancia, no una clase? – Keith

3

Así es como se puede crear dinámicamente una clase llamada Child en su código, asumiendo Parent ya existe ... incluso si no tiene una clase explícita Parent, puede usar object ...

El código siguiente define __init__() y luego lo asocia con la clase.

>>> child_name = "Child" 
>>> child_parents = (Parent,) 
>>> child body = """ 
def __init__(self, arg1): 
    # Initialization for the Child class 
    self.foo = do_something(arg1) 
""" 
>>> child_dict = {} 
>>> exec(child_body, globals(), child_dict) 
>>> childobj = type(child_name, child_parents, child_dict) 
>>> childobj.__name__ 
'Child' 
>>> childobj.__bases__ 
(<type 'object'>,) 
>>> # Instantiating the new Child object... 
>>> childinst = childobj() 
>>> childinst 
<__main__.Child object at 0x1c91710> 
>>> 
76

Descubrí la respuesta a la pregunta que tuve que me trajo a esta página. Como nadie ha sugerido realmente la respuesta a mi pregunta, pensé en publicarla.

class k: 
    pass 

a = k() 
k2 = a.__class__ 
a2 = k2() 

En este punto, a y a2 son instancias de la misma clase (clase k).

+1

Esta parece ser la respuesta correcta. Funciona y es simple. –

+0

Nota También puede pasar parámetros al constructor, si el __init__ los acepta 'a3 = k2 (7)' – gerardw

+0

¿Cuál es la diferencia entre 'k2 = un class__' .__ y' k2 = K'? –

2

Si tiene un módulo con una clase que desea importar, puede hacerlo de esta manera.

module = __import__(filename) 
instance = module.MyClass() 

Si no sabe de qué se llama la clase, puede recorrer las clases disponibles desde un módulo.

import inspect 
module = __import__(filename) 
for c in module.__dict__.values(): 
    if inspect.isclass(c): 
     # You may need do some additional checking to ensure 
     # it's the class you want 
     instance = c() 
Cuestiones relacionadas