2017-02-10 2 views
0

Betrachten Sie den Code in der Datei my_module.py:unerwartetes Verhalten während Python-Module mit Klassendefinitionen importieren

class A(object): 
    def __init__(self, x=er()): 
    self.x = x 

Nun, wenn ich dieses Modul importieren

import my_module 

ich eine Fehlermeldung erhalten,

name 'er is not defined 

Während ich verstehe, dass my_module er nicht definiert hat, aber ich nie erstellen eine Instanz von class A. Daher ist es verwirrend, dass Python versucht, den __init__ Callback auszuführen, wenn das Modul einfach importiert wird. Obwohl die __init__ Anruf nicht voll erklärt am Beispiel unten ausgeführt:

class A(object): 
    def __init__(self, x=5): 
    self.x = x 
    print ('I am here') 

Nun, wenn ich das Modul importieren - nichts gedruckt wird, und dieses Verhalten erwartet wird.

Ich bin verwirrt, warum die Funktion er in dem ersten Beispiel aufgerufen wird, wenn ich nicht ein Objekt class A instanziieren. Irgendwelche Hinweise auf die Dokumentation, die das erklärt?

+0

Wie auch immer, 'x' fungiert hier nicht als Rückruf, wenn Sie das meinen. Sie können nur einen Parameter 'er' haben und in' _init__' können Sie 'self.x = er()' eingeben –

Antwort

3

Da in Python die Standardargumentwerte unter Definitionszeit ausgewertet werden. Siehe zum Beispiel dieses question oder this notorious question.

Dies wird dokumentiert here

Die Vorgabewerte werden an dem Punkt der Funktionsdefinition ausgewertet in dem definierenden Umfang, so dass

i = 5 

def f(arg=i): 
    print(arg) 

i = 6 

f() drucken 5.

Wichtige Warnung: Der Standardwert wird nur einmal ausgewertet. Diese macht einen Unterschied, wenn der Standardwert ein veränderbares Objekt wie eine Liste, ein Wörterbuch oder Instanzen der meisten Klassen ist. Zum Beispiel sammelt die folgende Funktion, um die an sie übergebenen Argumente auf nachfolgenden Aufrufen:

def f(a, L=[]): 
    L.append(a) 
    return L 

print(f(1)) 
print(f(2)) 
print(f(3)) 

Diese

[1] 
[1, 2] 
[1, 2, 3] 

gedruckt wird Wenn Sie nicht möchten, dass der Standard zwischen nachfolgenden Aufrufen gemeinsam genutzt werden, können Sie die Funktion wie diese stattdessen schreiben:

def f(a, L=None): 
    if L is None: 
     L = [] 
    L.append(a) 
    return L