2017-08-23 4 views
-1

Supposons que certaines classes soient définies et disponibles dans l'espace de noms global. Dans l'exemple:Comment appeler le constructeur de classe ayant son nom dans la variable de texte? [Python]

class Point: 
    def __init__(self, x, y): 
     self.x = x 
     self.y = y 

class Vector: 
    def __init__(self, alpha, r): 
     self.x = r * cos(alpha) 
     self.y = r * sin(alpha) 

# and many others... 

Comment faire ceci:

class_name = 'Point' 
x = 14.361 
y = -8.100 
code_str = 'class_object = ' + class_name + '(' + str(x) + ', ' + str(y) + ')' 

exec code_str # That evaluates to: "class_object = Point(14.361, -8.100)" 

print class_object.x, class_object.y 

sans utiliser le exec dangereux?

PS. J'ai l'intention de charger les données à partir d'un fichier txt ou json si quelqu'un le demande.

+0

Charger les données, les chaînes à exécuter? On dirait une mauvaise idée. –

+0

Vous n'avez pas besoin de 'exec' du tout. Chargez simplement vos données à partir de votre fichier texte, et passez-le au constructeur de la classe 'Point'. Simple. –

+0

je sais que l'exécution du code à partir du fichier est très mauvaise idée :) mais j'ai beaucoup de classes - Point, ligne, Versor, et je ne sais pas à l'avance que je vais appeler –

Répondre

1

Si la classe est définie ou importée dans le même module, vous pouvez utiliser quelque chose comme:

globals()[class_name](x, y) 

si vous avez beaucoup de classes pour manipuler, vous devrait mieux utiliser un dictionnaire pour les stocker, la clé est le nom, la valeur est alors classe,

vous pouvez l'appeler avec:

my_classes = {'Point' : Point, 'Point2' : Point2} 

class_name = 'Point' 
x = 14.361 
y = -8.100 
my_classes[class_name](x, y) 
2

Si une classe est définie dans (ou importée) dans l'espace de noms global, vous pouvez obtenir une référence à l'aide du dictionnaire globals(). Après cela, il suffit d'appeler cela de la manière habituelle:

class_name = "Point" 
args = {"x": 14.361, "y": -8.100} 
Point = globals()[class_name] 
class_instance = Point(**args) 
-1

Vous pouvez utiliser eval.

class Point: 
    def __init__(self, x, y): 
     self.x = x 
     self.y = y 

class Vector: 
    def __init__(self, x, y): 
     self.x = x+100 
     self.y = y+100 

class_name = 'Vector' 

x = 10 
y = 20 
caller = '{}({},{})'.format(class_name,x,y) 
ob = eval(caller) 

print ob.x, ob.y