Es ist erwähnenswert, dass es für das jeweilige Problem mehrere Alternativen zur Verwendung gibt eval
:
Das einfachste ist, wie bereits erwähnt, die Verwendung von setattr
:
def __init__(self):
for name in attsToStore:
setattr(self, name, None)
Ein weniger offensichtlicher Ansatz besteht darin, das Objekt des __dict__
Objekts direkt zu aktualisieren . Wenn Sie lediglich die Attribute initialisieren möchten, ist None
dies weniger einfach als oben beschrieben. Aber bedenken Sie Folgendes:
def __init__(self, **kwargs):
for name in self.attsToStore:
self.__dict__[name] = kwargs.get(name, None)
Auf diese Weise können Sie Schlüsselwortargumente an den Konstruktor übergeben, z.
s = Song(name='History', artist='The Verve')
Es ermöglicht Ihnen auch, Ihre Verwendung locals()
expliziter zu gestalten, z.
s = Song(**locals())
... und wenn Sie wirklich None
den Attributen zuweisen möchten, deren Namen sich befinden in locals()
:
s = Song(**dict([(k, None) for k in locals().keys()]))
Ein anderer Ansatz zum Bereitstellen von Standardwerten für ein Objekt für eine Liste von Attributen besteht darin, die __getattr__
Methode der Klasse zu definieren :
def __getattr__(self, name):
if name in self.attsToStore:
return None
raise NameError, name
Diese Methode wird aufgerufen, wenn das benannte Attribut nicht auf normale Weise gefunden wird. Dieser Ansatz ist etwas unkomplizierter als das einfache Festlegen der Attribute im Konstruktor oder das Aktualisieren des__dict__
Er hat jedoch den Vorteil, dass das Attribut nur dann erstellt wird, wenn es vorhanden ist, was die Speichernutzung der Klasse erheblich reduzieren kann.
Der Sinn all dessen: Es gibt im Allgemeinen viele Gründe, die zu vermeiden sind eval
- das Sicherheitsproblem beim Ausführen von Code, den Sie nicht kontrollieren, das praktische Problem des Codes, den Sie nicht debuggen können usw. Aber ein noch wichtigerer Grund ist, dass Sie es im Allgemeinen nicht verwenden müssen. Python stellt dem Programmierer so viele seiner internen Mechanismen zur Verfügung, dass Sie selten wirklich Code schreiben müssen, der Code schreibt.
exec/eval
und wussten es immer noch nichtsetattr
?