Использование переменных для имен классов в Python?
-
03-07-2019 - |
Вопрос
Я хочу знать, как использовать переменные для имен объектов и функций в Python.В PHP вы можете сделать это:
$className = "MyClass";
$newObject = new $className();
Как вы делаете подобные вещи на Python?Или я совершенно не понимаю какого-то фундаментального различия с Python, и если да, то в чем оно?
Решение
В Python
className = MyClass
newObject = className()
В первой строке переменная className
ссылается на то же самое, что и MyClass
. Затем следующая строка вызывает конструктор MyClass
через переменную className
.
В качестве конкретного примера:
>>> className = list
>>> newObject = className()
>>> newObject
[]
(В Python list
является конструктором класса list
.)
Разница в том, что в PHP вы представляете имя класса, на который хотите ссылаться, как строку, а в Python вы можете напрямую ссылаться на тот же класс. Если вы должны использовать строку (например, если имя класса создается динамически), то вам нужно будет использовать другие методы.
Другие советы
Предполагая, что у some_module есть класс с именем " имя_класса ":
import some_module
klass = getattr(some_module, "class_name")
some_object = klass()
Я должен отметить, что вы должны быть осторожны: превращение строк в код может быть опасным, если строка получена от пользователя, поэтому в этой ситуации следует помнить о безопасности. :) Р>
Еще один метод (при условии, что мы все еще используем " имя_класса "):
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 параметра:имя, базы, атрибуты
>>> 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
Но вы также можете сделать это, о чем я думаю, вы спрашиваете:
>>> a = "MyClass"
>>> y = eval(a)()
MyClass
Но будьте очень осторожны с тем, где взять строку, которую вы используете " eval () " на - если это исходит от пользователя, вы по сути создаете огромную дыру в безопасности.
Обновление: использование type ()
, как показано в ответе coleifer, намного превосходит это решение.