Использование globals() для создания экземпляров класса
Я использую 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:
.
.
Я сделал это, чтобы избежать длинной лестницы if-else.
Каковы плюсы и минусы этого метода ?
Есть ли какой-либо альтернативный метод для того же самого ?
Создает ли это угрозу безопасности ?
1 ответ:
любое имя в ваших глобалах доступно; это включает в себя функцию
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__()}