2010-02-22 13 views
8

Ich bemerken folgend:Standardwert in einer Funktion in Python

class c: 
    def __init__(self, data=[]): 
    self._data=data 
a=c() 
b=c() 
a._data.append(1) 
print b._data 
[1] 

Ist das das richtige Verhalten?

+2

Bitte lesen Sie die Markup-Dokumentation, um zu sehen, wie Sie den Code korrekt formatieren. Es ist auf der rechten Seite der Seite. Bitte aktualisieren Sie Ihre Frage, um den Code 4 Leerzeichen einzurücken. –

+0

Related: http://stackoverflow.com/questions/1011431/python-things-one-must-avoid, http://stackoverflow.com/questions/1534407/python-object-intialisation-bug-or-am-i -misunderstanding-how-objects-work, http://stackoverflow.com/questions/1651154/why-are-default-arguments-evaluated-at-definition-time-in-python –

Antwort

11

Ja, es ist korrektes Verhalten.

Aber aus Ihrer Frage scheint es, dass es nicht das ist, was Sie erwartet haben.

Wenn Sie es, Ihre Erwartungen entsprechen, der folgend beachten:

Regel 1. nicht veränderbare Objekte als Standardwert anwenden.

def anyFunction(arg=[]): 

Erstellt kein neues Listenobjekt. Das Standardlistenobjekt für arg wird überall freigegeben.

Ähnlich

def anyFunction(arg={}): 

wird kein frisches dict-Objekt erstellen. Dieses Standarddikt wird geteilt.

class MyClass(object): 
    def __init__(self, arg= None): 
     self.myList= [] if arg is None else arg 

, die einen gemeinsamen Weg, ein Standardargument Wert zu schaffen, die eine frische, leere Liste Objekt ist.

+3

'Wird nie funktionieren.' ist ein bisschen hart. 'Wird dir bei jedem Anruf kein neues leeres veränderbares Objekt geben', scheint etwas ausgeglichener zu sein. Wenn Sie wissen, dass dies geschieht, möchten Sie dieses Verhalten möglicherweise tatsächlich verwenden. – MattH

+0

@MattH: Die Wiederverwendung desselben veränderbaren Objekts über einen Standardwert ist so merkwürdig, dass es keinen vernünftigen Anwendungsfall findet. Es ist ein * Standard * -Wert, daher kann es (oder auch nicht) als solches verwendet werden, abhängig von der Verwendung der Schnittstelle durch den Client. Es wäre so schwierig, Probleme damit zu diagnostizieren, dass ich zu meiner ursprünglichen Formulierung stehe. Speziell für n00bz. –

+0

Sie sollten ein Beispiel hinzufügen, wie Sie das umgehen können. Ansonsten ist die Antwort gut und richtig. – ironfroggy

1

Immer Funktionen machen wie diese dann:

def __init__ (self, data = None): 
    if data is None: 
     data = [] 

    self._data = data 

Alternativ Sie auch data = data or [] verwenden könnten, aber das hindert den Benutzer vorbei leer Parameter ('', 0, False usw.).

+0

Natürlich können Sie auch 'wenn nicht Daten: data = []' tun. – voyager

+0

Ihr Beispiel 'data = data oder []' funktioniert problemlos, wenn leere Listen übergeben werden. Du würdest sagen, dass 'data'' '[] oder []' sein wird, so dass es sich bei der ersten anschaut und sieht, dass es zu "false" führt, dann wird es den anderen Wert annehmen. – tgray

+1

Ich weiß, mein Punkt war, dass, wenn Sie zum Beispiel 'False' übergeben, '[]' als Wert verwendet wird, obwohl Sie 'False' übergeben haben. – poke

Verwandte Themen