Использование переменных для имен классов в 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, list является конструктором для list класса.)

разница в том, что в PHP вы представляете имя класса, на который хотите ссылаться как на строку, а в Python вы можете ссылаться на тот же класс напрямую. Если ты ... --17-->должны используйте строку (например, если имя класса создается динамически), тогда вам нужно будет использовать другие методы.


предполагая, что 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

но вы также можете сделать это, и я думаю, что вы спрашиваете:

>>> a = "MyClass"
>>> y = eval(a)()
MyClass

но будьте очень осторожны с тем, где вы получаете строку, которую вы используете "eval ()" На -- если она исходит от пользователя, вы по существу создаете огромную дыру в безопасности.

Обновление: Используя type() как показано в ответе coleifer, намного превосходит это решение.