Usando variáveis ??para a classe Nomes em Python?
-
03-07-2019 - |
Pergunta
Eu quero saber como usar variáveis ??para objetos e nomes de função em Python. Em PHP, você pode fazer isso:
$className = "MyClass";
$newObject = new $className();
Como você faz esse tipo de coisa em Python? Ou, eu sou totalmente não apreciando alguma diferença fundamental com Python, e se assim for, o que é?
Solução
Em Python,
className = MyClass
newObject = className()
A primeira linha faz com que a variável className
referem-se a mesma coisa que MyClass
. Em seguida, a próxima linha chama o construtor MyClass
através da variável className
.
Como um exemplo concreto:
>>> className = list
>>> newObject = className()
>>> newObject
[]
(Em Python, list
é o construtor para a classe list
.)
A diferença é que em PHP, você representa o nome da classe que você deseja se referem como uma corda, enquanto em Python você pode fazer referência a mesma classe diretamente. Se você deve usar uma string (por exemplo, se o nome da classe é criada dinamicamente), então você vai precisar usar outras técnicas.
Outras dicas
Assumindo que some_module tem uma classe chamada "class_name":
import some_module
klass = getattr(some_module, "class_name")
some_object = klass()
Gostaria de salientar que você deve ter cuidado aqui: transformando as strings em código pode ser perigoso se a corda veio do usuário, de modo que você deve ter em mente a segurança nesta situação. :)
Um outro método (assumindo que ainda estamos usando "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
O último método é provavelmente a maneira mais segura de fazer isso, por isso é provavelmente o que você deve usar, se possível.
Se você precisa criar uma classe dinâmica em Python (ou seja, aquele cujo nome é uma variável), você pode usar o tipo (), que leva 3 parâmetros: nome, bases, attrs
>>> class_name = 'MyClass'
>>> klass = type(class_name, (object,), {'msg': 'foobarbaz'})
<class '__main__.MyClass'>
>>> inst = klass()
>>> inst.msg
foobarbaz
- Note no entanto, que isso não significa 'instanciar' o objeto (ou seja, não chama construtores etc. Ele cria um novo (!) Classe com o mesmo nome.
Se você tem este:
class MyClass:
def __init__(self):
print "MyClass"
Em seguida, você costuma fazer isso:
>>> x = MyClass()
MyClass
Mas você também pode fazer isso, que é o que eu acho que você está perguntando:
>>> a = "MyClass"
>>> y = eval(a)()
MyClass
Mas, ser muito cuidadosos sobre onde obter a seqüência que você use "eval ()" on -. Se ele está vindo do usuário, você está criando essencialmente uma falha de segurança enorme
Update:. Usando type()
como mostra a resposta de coleifer é muito superior a esta solução