Использование переменных для имен классов в Python?
Я хочу знать, как использовать переменные для имен объектов и функций в Python. В PHP вы можете сделать это:
$className = "MyClass";
$newObject = new $className();
Как вы это делаете в Python? Или я совершенно не понимаю фундаментальное отличие от Python, и если да, то что это?
Ответы
Ответ 1
В Python
className = MyClass
newObject = className()
Первая строка делает переменную className
ссылкой на ту же вещь, что и MyClass
. Затем следующая строка вызывает конструктор MyClass
через переменную className
.
В качестве конкретного примера:
>>> className = list
>>> newObject = className()
>>> newObject
[]
(В Python list
является конструктором класса list
.)
Разница в том, что в PHP вы представляете имя класса, который вы хотите назвать строкой, а в Python вы можете напрямую ссылаться на тот же класс. Если вы должны использовать строку (например, если имя класса создается динамически), вам нужно будет использовать другие методы.
Ответ 2
Предполагая, что some_module имеет класс с именем "class_name":
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
Последний способ, вероятно, самый безопасный способ сделать это, поэтому, вероятно, вы должны использовать, если это вообще возможно.
Ответ 3
Если вам нужно создать динамический класс в Python (т.е. тот, чье имя является переменной), вы можете использовать type(), который принимает 3 параметра:
имя, базы, attrs
>>> class_name = 'MyClass'
>>> klass = type(class_name, (object,), {'msg': 'foobarbaz'})
<class '__main__.MyClass'>
>>> inst = klass()
>>> inst.msg
foobarbaz
- Обратите внимание, что это не "создает экземпляр" объекта (т.е. не вызывает конструкторы и т.д.). Он создает новый (!) класс с тем же именем.
Ответ 4
Если у вас есть это:
class MyClass:
def __init__(self):
print "MyClass"
Затем вы обычно делаете это:
>>> x = MyClass()
MyClass
Но вы также можете это сделать, и я думаю, что вы спрашиваете:
>>> a = "MyClass"
>>> y = eval(a)()
MyClass
Но будьте очень осторожны, когда вы получаете строку, в которой вы используете "eval()", - если она исходит от пользователя, вы, по сути, создаете огромную дыру в безопасности.
Обновление: использование type()
, как показано в ответе coleifer, намного превосходит это решение.