23 votes

Python paramètres optionnels

Les gars, je viens de commencer python récemment et se confondre avec les paramètres facultatifs, dis-je avoir le programme comme ceci:

class B:
   pass

class A:
    def __init__(self, builds = B()):
        self.builds = builds

Si je crée Un deux fois

b = A()
c = A()

et imprimer leurs constructions

print b.builds
print c.builds

J'ai trouvé qu'ils utilisent exactement le même objet,

<__main__.B instance at 0x68ee0>
<__main__.B instance at 0x68ee0>

Mais ce n'est pas ce que je veux, car si l' b changé une partie interne de l'état de versions, l'une en c objet seront également modifiés.

Est-il possible de recréer cette option paramètres à chaque fois par l'utilisation de cette option paramètres de la syntaxe?

45voto

Robert Rossney Points 43767

Vous avez besoin de comprendre comment les valeurs par défaut de travail afin de les utiliser efficacement.

Les fonctions sont des objets. En tant que tels, ils ont des attributs. Donc, si j'ai créer cette fonction:

>>> def f(x, y=[]):
        y.append(x)
        return y

J'ai créé un objet. Voici ses caractéristiques:

>>> dir(f)
['__call__', '__class__', '__closure__', '__code__', '__defaults__', '__delattr__',   
'__dict__', '__doc__', '__format__', '__get__', '__getattribute__', '__globals__',    
'__hash__', '__init__', '__module__', '__name__', '__new__', '__reduce__', 
'__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 
'func_closure', 'func_code', 'func_defaults', 'func_dict', 'func_doc', 'func_globals', 
'func_name']

L'un d'eux est - func_defaults. Qui semble prometteuse, ce qui est là?

>>> f.func_defaults
([],)

C'est un n-uplet qui contient la fonction par défaut de valeurs. Si une valeur par défaut est un objet, le tuple contient une instance de cet objet.

Cela conduit à quelques-uns assez comportement contre-intuitif si vous êtes en train de penser qu' f ajoute un élément à une liste, de revenir une liste contenant uniquement si aucune liste n'est fournie:

>>> f(1)
[1]
>>> f(2)
[1, 2]

Mais si vous savez que la valeur par défaut est une instance d'objet stocké dans un de la de la fonction d'attributs, c'est beaucoup moins contre-intuitif:

>>> x = f(3)
>>> y = f(4)
>>> x == y
True
>>> x
[1, 2, 3, 4]
>>> x.append(5)
>>> f(6)
[1, 2, 3, 4, 5, 6]

Sachant cela, il est évident que si vous souhaitez une valeur par défaut d'une fonction du paramètre à une nouvelle liste (ou de tout nouvel objet), vous ne pouvez pas simplement stash une instance de l'objet en func_defaults. Vous devez en créer un nouveau à chaque fois que la fonction est appelée:

>>>def g(x, y=None):
       if y==None:
           y = []
       y.append(x)
       return y

13voto

SilentGhost Points 79627

vous devez faire ce qui suit:

class A:
    def __init__(self, builds=None):
        if builds is None:
            builds = B()
        self.builds = builds

c'est un très répandue erreur, à l'aide mutable paramètres par défaut arguments. il y a beaucoup de dupes probablement sur DONC.

6voto

Jonathan Feinberg Points 24791

Oui; par défaut les paramètres sont évalués seulement au moment où la fonction est définie.

Une solution possible serait d'avoir le paramètre être une classe plutôt qu'une instance, à la

def foo(blah, klass = B):
    b = klass()
    # etc

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X