Wenn eine Zeichenfolge als Benutzereingabe für eine Python-Funktion angegeben wird, möchte ich ein Klassenobjekt daraus entfernen, wenn sich im aktuell definierten Namespace eine Klasse mit diesem Namen befindet. Im Wesentlichen möchte ich die Implementierung für eine Funktion, die diese Art von Ergebnis erzeugt:
class Foo:
pass
str_to_class("Foo")
==> <class __main__.Foo at 0x69ba0>
Ist das überhaupt möglich?
Antworten:
Das scheint am einfachsten zu sein.
quelle
Das könnte funktionieren:
quelle
def str_to_class(str): return vars()[str]
?Sie könnten so etwas tun wie:
quelle
globals()
... eine andere Sache, die vermieden werden sollteglobals()
wohl weit weniger schlecht alseval
und nicht wirklich schlechter alssys.modules[__name__]
AFAIK.Sie möchten die Klasse
Baz
, die im Modul lebtfoo.bar
. Mit Python 2.7 möchten Sie Folgendes verwendenimportlib.import_module()
, da dies den Übergang zu Python 3 erleichtert:Mit Python <2.7:
Verwenden:
quelle
Dies behandelt sowohl Klassen im alten als auch im neuen Stil genau.
quelle
Ich habe mir angesehen, wie Django damit umgeht
django.utils.module_loading hat dies
Sie können es wie verwenden
import_string("module_path.to.all.the.way.to.your_class")
quelle
Ja, das kannst du machen. Angenommen, Ihre Klassen befinden sich im globalen Namespace.
quelle
In Bezug auf die Ausführung von beliebigem Code oder unerwünschte vom Benutzer übergebene Namen können Sie eine Liste akzeptabler Funktions- / Klassennamen haben. Wenn die Eingabe mit einer in der Liste übereinstimmt, wird sie ausgewertet.
PS: Ich weiß ... ein bisschen spät ... aber es ist für alle anderen, die in Zukunft darüber stolpern.
quelle
Die Verwendung von importlib hat für mich am besten funktioniert.
Dies verwendet die Zeichenfolgenpunktnotation für das Python-Modul, das Sie importieren möchten.
quelle
Wenn Sie Klassen, die Sie mit einer Zeichenfolge erstellen, wirklich abrufen möchten, sollten Sie sie in einem Wörterbuch speichern (oder richtig formulieren, referenzieren ). Auf diese Weise können Sie Ihre Klassen auch auf einer höheren Ebene benennen und unerwünschte Klassen vermeiden.
Beispiel aus einem Spiel, in dem in Python Schauspielerklassen definiert sind und Sie vermeiden möchten, dass andere allgemeine Klassen durch Benutzereingaben erreicht werden.
Ein anderer Ansatz (wie im folgenden Beispiel) würde darin bestehen, eine völlig neue Klasse zu erstellen, die die
dict
oben genannten enthält. Das würde:Beispiel:
Das bringt mich zurück:
Ein weiteres lustiges Experiment, das damit zu tun hat, ist das Hinzufügen einer Methode, die das einbindet,
ClassHolder
damit Sie nie alle Klassen verlieren, die Sie gemacht haben: ^)quelle