我正在使用globals()来动态创建类的实例。
例如。
animals.py
class Cat():
pass
class Dog():
pass
test.py
#import animals
def create_animal():
# Take 'which_animal' input from
# somewhere in form of string
try:
animal1 = globals()[which_animal]()
catch:
.
.
我这样做是为了避免长时间的其他梯子
这种方法的优点和缺点是什么?
是否有相同的替代方法?
它是否会产生安全威胁?
答案 0 :(得分:3)
您的全局变量中的任何名称都可以访问;这包括create_animal()
函数以及您可能已导入的任何内容。
这意味着可能存在安全风险,具体取决于导入的内容。您至少应该过滤__module__
属性中找到的对象:
animal_cls = globals()[which_animal]
if animal_cls.__module__ != __name__:
raise TypeError('Not a class defined in this module!')
animal1 = animal_cls()
另一种方法是将您想要的类放在某种数据结构中。您可以使用新词典:
animals = {
'Cat': Cat,
'Dog': Dog,
}
您可以让每个类自己(通过装饰器)注册到这样的映射中:
animals = {}
def registered(cls):
animals[cls.__name__] = cls
return cls
@registered
class Cat():
pass
@registered
class Dog():
pass
或者您可以使用基类;然后,__subclasses__()
方法允许您列出任何和所有派生类:
class Animal(object):
pass
class Cat(Animal):
pass
class Dog(Animal):
pass
animals = {cls.__name__: cls for cls in Animal.__subclasses__()}