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 Nonedies 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 Noneden 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/evalund wussten es immer noch nichtsetattr?