Использование переменных для имен классов в Python?
Я хочу знать, как использовать переменные для имен объектов и функций в Python. В PHP вы можете сделать следующее:
$className = "MyClass";
$newObject = new $className();
Как вы делаете такие вещи в Python? Или, может быть, я совершенно не понимаю некоторого фундаментального различия с Python, и если да, то в чем оно заключается?
4 ответа:
В Python,
className = MyClass newObject = className()
Первая строка заставляет переменную
className
ссылаться на то же самое, что иMyClass
. Затем следующая строка вызывает конструкторMyClass
через переменнуюclassName
.В качестве конкретного примера:
>>> className = list >>> newObject = className() >>> newObject []
(в Python,
Разница в том, что в PHP вы представляете имя класса, на который хотите ссылаться, как строку, в то время как в Python вы можете ссылаться на тот же самый класс напрямую. Если вы должны использовать string (например, если имя класса создается динамически), то вам нужно будет использовать другие методы.list
является конструктором для классаlist
.)
Предполагая, что some_module имеет класс с именем "class_name":
import some_module klass = getattr(some_module, "class_name") some_object = klass()
Я должен отметить, что вы должны быть осторожны здесь: превращение строк в код может быть опасным, если строка пришла от пользователя, поэтому вы должны иметь в виду безопасность в этой ситуации. :)
Еще один метод (предполагая, что мы все еще используем "class_name"):
Последний метод, вероятно, является наиболее безопасным способом сделать это, так что это, вероятно, то, что вы должны использовать, если это вообще возможно.class_lookup = { 'class_name' : class_name } some_object = class_lookup['class_name']() #call the object once we've pulled it out of the dict
Если вам нужно создать динамический класс в Python (то есть тот, чье имя является переменной), вы можете использовать type (), который принимает 3 парама: имя, основания, attrs
>>> class_name = 'MyClass' >>> klass = type(class_name, (object,), {'msg': 'foobarbaz'}) <class '__main__.MyClass'> >>> inst = klass() >>> inst.msg foobarbaz
Заметьте, однако, что это не "инстанцирует" объект (т. е. не вызывает конструкторы и т. д. Он создает новый(!) класс с тем же именем.
Если у вас есть это:
class MyClass: def __init__(self): print "MyClass"
Затем вы обычно делаете следующее:
>>> x = MyClass() MyClass
Но вы могли бы также сделать это, о чем, я думаю, вы просите:
Но будьте очень осторожны с тем, где вы получаете строку, в которой вы используете "eval ()" - если она исходит от пользователя, вы, по сути, создаете огромную дыру в безопасности.>>> a = "MyClass" >>> y = eval(a)() MyClass
Обновление: использование
type()
, как показано в ответе колейфера, намного превосходит это решение.