una str resueltos programacion poo orientada objetos metodo instanciar importar ejercicios ejemplos ejemplo como clases clase __str__ python

str - programacion orientada a objetos python ejemplos pdf



¿Convertir cadena a objeto de clase Python? (10)

Advertencia : eval() se puede usar para ejecutar código Python arbitrario. Nunca debe usar eval() con cadenas no confiables. (Consulte Security of Python''s eval () en cadenas no confiables? )

Esto parece más simple.

>>> class Foo(object): ... pass ... >>> eval("Foo") <class ''__main__.Foo''>

Dada una cadena como entrada de usuario a una función de python, me gustaría obtener un objeto de clase si hay una clase con ese nombre en el espacio de nombres actualmente definido. Básicamente, quiero la implementación de una función que produzca este tipo de resultados:

class Foo: pass str_to_class("Foo") ==> <class __main__.Foo at 0x69ba0>

es posible?


En términos de ejecución de código arbitrario, o nombres pasados ​​de usuarios no deseados, podría tener una lista de nombres de funciones / clases aceptables, y si la entrada coincide con uno en la lista, se evalúa.

PD: Lo sé ... un poco tarde ... pero es para cualquier otra persona que tropiece con esto en el futuro.


Esto podría funcionar:

import sys def str_to_class(classname): return getattr(sys.modules[__name__], classname)


He visto cómo maneja django esto

django.utils.module_loading tiene esto

def import_string(dotted_path): """ Import a dotted module path and return the attribute/class designated by the last name in the path. Raise ImportError if the import failed. """ try: module_path, class_name = dotted_path.rsplit(''.'', 1) except ValueError: msg = "%s doesn''t look like a module path" % dotted_path six.reraise(ImportError, ImportError(msg), sys.exc_info()[2]) module = import_module(module_path) try: return getattr(module, class_name) except AttributeError: msg = ''Module "%s" does not define a "%s" attribute/class'' % ( module_path, class_name) six.reraise(ImportError, ImportError(msg), sys.exc_info()[2])

Puede usarlo como import_string("module_path.to.all.the.way.to.your_class")


Podrías hacer algo como:

globals()[class_name]


Quieres la clase "Baz", que vive en el módulo "foo.bar". Con python 2.7, desea utilizar importlib.import_module (), ya que esto facilitará la transición a python 3:

import importlib def class_for_name(module_name, class_name): # load the module, will raise ImportError if module cannot be loaded m = importlib.import_module(module_name) # get the class, will raise AttributeError if class cannot be found c = getattr(m, class_name) return c

Con python <2.7:

def class_for_name(module_name, class_name): # load the module, will raise ImportError if module cannot be loaded m = __import__(module_name, globals(), locals(), class_name) # get the class, will raise AttributeError if class cannot be found c = getattr(m, class_name) return c

Utilizar:

loaded_class = class_for_name(''foo.bar'', ''Baz'')


Sí, usted puede hacer esto. Suponiendo que sus clases existen en el espacio de nombres global, algo como esto lo hará:

import types class Foo: pass def str_to_class(s): if s in globals() and isinstance(globals()[s], types.ClassType): return globals()[s] return None str_to_class(''Foo'') ==> <class __main__.Foo at 0x340808cc>


Si realmente desea recuperar las clases que crea con una cadena, debe almacenarlas (o redactarlas correctamente, hacer una referencia ) en un diccionario. Después de todo, eso también permitirá nombrar tus clases en un nivel superior y evitar exponer las clases no deseadas.

Ejemplo, de un juego donde las clases de actor están definidas en Python y quieres evitar que otras clases generales sean alcanzadas por la entrada del usuario.

Otro enfoque (como en el ejemplo a continuación) sería crear una nueva clase completa, que contenga el dict anterior. Esto sería:

  • Permita que se creen múltiples titulares de clases para una organización más fácil (como, una para las clases de actores y otra para los tipos de sonido);
  • Hacer modificaciones tanto al titular como a las clases que se realizan con mayor facilidad;
  • Y puede usar métodos de clase para agregar clases al dict. (Aunque la abstracción a continuación no es realmente necesaria, es meramente para ... "ilustración" ).

Ejemplo:

class ClassHolder(object): def __init__(self): self.classes = {} def add_class(self, c): self.classes[c.__name__] = c def __getitem__(self, n): return self.classes[n] class Foo(object): def __init__(self): self.a = 0 def bar(self): return self.a + 1 class Spam(Foo): def __init__(self): self.a = 2 def bar(self): return self.a + 4 class SomethingDifferent(object): def __init__(self): self.a = "Hello" def add_world(self): self.a += " World" def add_word(self, w): self.a += " " + w def finish(self): self.a += "!" return self.a aclasses = ClassHolder() dclasses = ClassHolder() aclasses.add_class(Foo) aclasses.add_class(Spam) dclasses.add_class(SomethingDifferent) print aclasses print dclasses print "=======" print "o" print aclasses["Foo"] print aclasses["Spam"] print "o" print dclasses["SomethingDifferent"] print "=======" g = dclasses["SomethingDifferent"]() g.add_world() print g.finish() print "=======" s = [] s.append(aclasses["Foo"]()) s.append(aclasses["Spam"]()) for a in s: print a.a print a.bar() print "--" print "Done experiment!"

Esto me devuelve:

<__main__.ClassHolder object at 0x02D9EEF0> <__main__.ClassHolder object at 0x02D9EF30> ======= o <class ''__main__.Foo''> <class ''__main__.Spam''> o <class ''__main__.SomethingDifferent''> ======= Hello World! ======= 0 1 -- 2 6 -- Done experiment!

Otro experimento divertido que hacer con ellos es agregar un método que salmuera el ClassHolder para que nunca pierdas todas las clases que hiciste: ^)


Usar importlib funcionó lo mejor para mí.

import importlib importlib.import_module(''accounting.views'')

Utiliza la notación de punto de cadena para el módulo de python que desea importar.


import sys import types def str_to_class(field): try: identifier = getattr(sys.modules[__name__], field) except AttributeError: raise NameError("%s doesn''t exist." % field) if isinstance(identifier, (types.ClassType, types.TypeType)): return identifier raise TypeError("%s is not a class." % field)

Esto maneja con precisión tanto las clases antiguas como las nuevas.