Il convient de noter que pour le problème spécifique en question, il existe plusieurs alternatives à l'utilisation eval
:
Le plus simple, comme indiqué, consiste à utiliser setattr
:
def __init__(self):
for name in attsToStore:
setattr(self, name, None)
Une approche moins évidente consiste à mettre à jour __dict__
directement l'objet de l' objet. Si tout ce que vous voulez faire est d'initialiser les attributs sur None
, c'est moins simple que ce qui précède. Mais considérez ceci:
def __init__(self, **kwargs):
for name in self.attsToStore:
self.__dict__[name] = kwargs.get(name, None)
Cela vous permet de transmettre des arguments de mot-clé au constructeur, par exemple:
s = Song(name='History', artist='The Verve')
Cela vous permet également de rendre votre utilisation locals()
plus explicite, par exemple:
s = Song(**locals())
... et, si vous voulez vraiment attribuer None
les attributs dont les noms se trouvent dans locals()
:
s = Song(**dict([(k, None) for k in locals().keys()]))
Une autre approche pour fournir un objet avec des valeurs par défaut pour une liste d'attributs consiste à définir la __getattr__
méthode de la classe :
def __getattr__(self, name):
if name in self.attsToStore:
return None
raise NameError, name
Cette méthode est appelée lorsque l'attribut nommé n'est pas trouvé de la manière normale. Cette approche est un peu moins simple que de simplement définir les attributs dans le constructeur ou de mettre à jour le __dict__
, mais elle a le mérite de ne pas créer réellement l'attribut à moins qu'il n'existe, ce qui peut réduire considérablement l'utilisation de la mémoire de la classe.
Le point de tout cela: il y a beaucoup de raisons, en général, à éviter eval
- le problème de sécurité de l'exécution de code que vous ne contrôlez pas, le problème pratique du code que vous ne pouvez pas déboguer, etc. Mais une raison encore plus importante est-ce que généralement, vous n'avez pas besoin de l'utiliser. Python expose tellement de ses mécanismes internes au programmeur que vous avez rarement vraiment besoin d'écrire du code qui écrit du code.
exec/eval
et ne saviez toujours passetattr
?