Qu'est-ce que vous pourriez faire:
class MyClass(object):
def __init__(self, **kwargs):
if not 'b' in kwargs:
print "warning"
self._a = kwargs.get('a', 0)
self._b = kwargs.get('b', 1)
Ce code utilise la fonction « get » d'un dictionnaire qui extrait la valeur stockée dans la clé (qui est le premier argument) et, si les clés n'existe pas , repli sur le deuxième argument qui est la valeur "par défaut".
Je ne sais pas si cela peut vous aider?
Python 2.7 "get" function for a dictionary
Mise à jour
Parce que la réponse de Thomas Kuhn était extrêmement intéressant, je voulais pousser encore plus loin:
class MyClass(object):
def __init__(self, **kwargs):
defaults = dict(a=0, b=1)
for key, value in defaults.iteritems():
if not key in kwargs:
print "Warning: default {0}={1} is used.".format(key, value)
kwargs.setdefault(key, value)
self.__dict__.update(kwargs)
m = MyClass()
print "a: {0}; b: {1}".format(m.a, m.b)
print "-"*30
m = MyClass(a=10)
print "a: {0}; b: {1}".format(m.a, m.b)
print "-"*30
m = MyClass(a=10, b=11)
print "a: {0}; b: {1}".format(m.a, m.b)
print "-"*30
De cette façon, vous pouvez avoir deux avantages principaux :
- Votre liste d'attributs sera ajoutée directement dans la classe en tant que paramètre afin que vous puissiez y accéder.
- La méthode
setdefault
extrait la valeur si la clé existe, et si ce n'est pas simplement ajoute la clé avec la valeur par défaut spécifiée.
Je comprends que ce code pourrait être extrêmement dangereux dans un environnement non contrôlé, de sorte que vous pouvez éventuellement fallback sur une structure plus complexe pour votre classe, en utilisant les méthodes:
__getattr__(self, attributename)
pour extraire la valeur d'attribut basée sur le nom défini, de sorte que vous pouvez conserver toutes vos valeurs dans une variable locale comme self.classparameters ou quelque chose
__setattr__(self, attributename, attributevalue)
pour définir la valeur.
Et ceci est le code:
class MyClass(object):
def __init__(self, **kwargs):
defaults = dict(a=0, b=1)
for key, value in defaults.iteritems():
if not key in kwargs:
print "Warning: default {0}={1} is used.".format(key, value)
kwargs.setdefault(key, value)
self.__dict__.update(kwargs)
def __getattr__(self, parameter):
return self.__dict__.get(parameter)
def __setattr__(self, parameter, value):
self.__dict__.update({parameter: value})
m = MyClass()
m.b = 11
print "a: {0}; b: {1}".format(m.a, m.b)
print "-"*30
m = MyClass(a=10)
m.b = 101
print "a: {0}; b: {1}".format(m.a, m.b)
print "-"*30
m = MyClass(a=10, b=11)
m.b = 1001
print "a: {0}; b: {1}".format(m.a, m.b)
print "-"*30
C'est quelque chose qui doit être portable avec un soin extrême parce que vous pouvez (et) ont des problèmes graves dans plusieurs situations.
Alerte: c'est pas une explication sur la façon d'utiliser __setattr__
et __getattr__
, au lieu est un simple (et stupide) façon d'aborder le même problème avec de multiples solutions, donc si vous savez comment améliorer ce bit avec une façon plus intelligente d'utiliser ces méthodes magiques , de rien.
Une autre façon de mettre en œuvre ce processus, qui pourrait être plus bavard, mais vous permet d'avoir beaucoup de contrôle de ce qui se passe utilise le @property décorateur:
class MyClass(object):
def __init__(self, **kwargs):
self.classparam = dict(a=0, b=1)
for key, value in self.classparam.iteritems():
if not key in kwargs:
print "Warning: default {0}={1} is used.".format(key, value)
kwargs.setdefault(key, value)
self.classparam.update(kwargs)
@property
def a(self):
return self.classparam.get('a')
@a.setter
def a(self, value):
self.classparam.update(a=value)
@property
def b(self):
return self.classparam.get('b')
@b.setter
def b(self, value):
self.classparam.update(b=value)
m = MyClass()
m.b = 10
print "a: {0}; b: {1}".format(m.a, m.b)
print "-"*30
m = MyClass(a=10)
m.b = 100
print "a: {0}; b: {1}".format(m.a, m.b)
print "-"*30
m = MyClass(a=10, b=11)
m.b = 1000
print "a: {0}; b: {1}".format(m.a, m.b)
print "-"*30
Pourriez-vous expliquer pourquoi vous auriez besoin d'avertir sur les valeurs par défaut? Si elles sont par défaut, je pense que la fonction devrait fonctionner normalement sans avertissement. – noel
Devrait-il y avoir un avertissement si quelqu'un appelle 'MyClass (0, 1)'? –
Eh bien .. la sensibilisation de l'utilisateur est toujours une bonne chose, et si l'utilisateur sait qu'une valeur par défaut spécifique est utilisée si elle n'est pas spécifiquement définie semble extrêmement intéressant. Cela pourrait aussi être utile dans une situation où la deuxième valeur change, si elle n'est pas spécifiée, basée sur les valeurs du premier argument .. –