2016-04-06 17 views
5

Mam tło z C++ i staram się nauczyć jakiegoś Pythona.Późne wiążące zamknięcia Pythona

Whist Rozumiem funkcje wirtualne dla C++, niestety nie rozumiem, co rozumie się przez późne wiązanie zamknięcia w python.

Link: https://gist.github.com/deemson/8efabf56d67623ead804

Copy-makaron z samouczka:

functions = [] 
for n in [1, 2, 3]: 
    def func(x): 
     return n*x 
    functions.append(func) 

# You would expect this to print [2, 4, 6] 
print(
    'calling a list of bad closures and output is: {}' 
    .format(str([function(2) for function in functions])) 
) 

Co dokładnie się tu dzieje? Kiedy funkcja jest dołączana do listy, jakie są jej wartości? Czy ktoś może uprościć ten kod, abym to zrozumiał.

Odpowiedz

1

Zauważ, że możesz tworzyć funkcje w środowisku wykonawczym, mniej więcej tak jak lambdas w języku C++. Więc w zasadzie jesteś iteracji na liście, co n przyjmować wartości 1,2 and 3

for n in [1, 2, 3]: 
    def func(x): 
     return n*x 

tak, by w każdej iteracji tworzona jest funkcja o nazwie func, ze przyjmuje wartość i mnoży je przez n. Dołączając go do listy funkcji, będziesz mieć zapisane te funkcje, dzięki czemu możesz przejrzeć listę, aby wywołać funkcje.

[function(2) for function in functions] 

Robiąc to nazywasz każdej z funkcji przechowywanych z wartością 2, można się spodziewać to wyjście [2, 4, 6] ([1 * 2, 2 * 2, 3 * 2]), lecz zwraca [6, 6, 6] , DLACZEGO ?, to dlatego, że dla każdej funkcji używamy n do jej obliczeń, więc tak naprawdę nie robimy 1*x, 2*x and 3*x, ale faktycznie , a ponieważ x jest wiązane w ostatnim czasie do , wszystkie funkcje robią 3*2, które stają się .

Poruszaj się za pomocą konsoli pythona, aby sprawdzić ją poprawnie.

0

W języku C++ wskaźnik do funkcji jest dołączany do listy. Po pętli for, functions zawiera wskaźniki do trzech różnych funkcji (func(x) = n * x,i). Zwróć uwagę na zależność od n. Wraz ze zmianami, tak samo zachowanie się tych funkcji będzie równoważne.

W drugiej części kodu wskaźniki są wyodrębniane z listy i każda z trzech funkcji jest oceniana z argumentem 2.

Oto kolejny przykład do wyjaśnienia. Wyobraźmy sobie, że to robimy:

>>> functions 
[<function func at 0x0239AA70>, <function func at 0x0239AAB0>, <function func at 0x0239AB30>] 
>>> g = functions[2] 
>>> g 
<function func at 0x0239AB30> 
>>> g(10) 
20 
>>> g(100) 
200 

W pierwszych wierszach widzimy, że funkcje zawierają wskaźniki do trzech różnych funkcji. Następny wiersz wyodrębnia trzeci wskaźnik z listy (który odnosi się do func(x) = n * x) i przypisuje go do g. Skutecznie, zdefiniowaliśmy funkcję g(x) = n * x z tym połączeniem. Możemy teraz ocenić argumenty za pomocą g.

Należy pamiętać, że ponieważ wszystkie funkcje zależą od n, można zmienić n, a zachowanie się zmieni.

>>> n = 100 
>>> g(10) 
1000 
+0

Ale czy to nie yeild [2 4 6] zamiast [6 6 6] – RickMota

+0

Odpowiedź Daniela jest prawidłowa - złapał coś, czego nie zrobiłem. Wszystkie odnoszą się do n, a ponieważ n ma ustaloną wartość 2 na końcu, wszystkie funkcje będą zachowywać się w ten sam sposób. – Christian

+0

Zmieniono, aby wspomnieć o zależności od n, i pozostawiam rozwiązanie opublikowane w celu wyjaśnienia połączenia ze wskaźnikami w C++. – Christian