-->

How to call class constructor having its name in t

2020-07-31 20:42发布

问题:

Let's assume we have some classes defined and available in global namespace. In example:

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...

How to do this:

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

without using the dangerous exec?

PS. I'm intending to load the data from some txt or json file if anyone asks.

回答1:

If the class is defined or imported in the same module, you could use something like :

globals()[class_name](x, y)

if you have many classes to handle, you should better use a dictionnary to store them, key is the name, value is the class,

then you can call it with :

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

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


回答2:

Provided that a class is defined in (or imported into) the global namespace, you can get a reference to it via the globals() dictionary. After that just call it the usual way:

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


回答3:

You can use 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