Python używa systemu czasami nazywanego call-by-object. Nic nie jest kopiowane podczas przekazywania argumentów do funkcji. Nazwy argumentów funkcji są lokalnie powiązane w treści funkcji, z tymi samymi obiektami podanymi w wywołaniu funkcji.
Różni się to od tego, co większość ludzi uważa za "połączenie według wartości", ponieważ nie kopiuje obiektów. Ale różni się także od "wywołania przez odwołanie", ponieważ odwołanie dotyczy obiektu --- jest powiązane, ale do tego samego obiektu. Oznacza to, że możesz zmutować obiekt przekazany, ale ponowne powiązanie nazwy wewnątrz funkcji nie ma wpływu poza funkcją. Prostym przykładem różnicy:
>>> def func(x):
... x[0] = 2 # Mutating the object affects the object outside the function
>>> myList = [1]
>>> func(myList)
>>> myList # myList has changed
[2]
>>> def func(x):
... x = 2 # rebinding name has no effect outside the function
>>> myList = [1]
>>> func(myList)
>>> myList # myList is unaffected
[1]
mój prosty sposób myślenia o to, że przypisanie do gołej nazwą --- czyli wypowiedzi postaci name = value
--- jest zupełnie inna od wszystkiego innego w Pythonie . Sposób działania na nazwach, a nie na wartościach, polega na wykonaniu name = value
. (Są tu dziwne wyjątki, takie jak zgranie z globals()
itd., Ale i tak są to niebezpieczne obszary). W szczególności name = value
różni się od obj.prop = value
, obj[0] = value
, obj += value
i innych podobnych rzeczy, które wyglądają jak przypisanie, ale faktycznie działają na obiektach a nie na nazwiska.
To powiedziawszy, wywołania funkcji w Pythonie mają pewną ilość narzutów samych w sobie (do ustawienia ramki wykonawczej itp.). Jeśli funkcja jest wywoływana wiele razy, ten narzut może spowodować zauważalny wpływ na wydajność. Podział jednej funkcji na wiele może mieć wpływ na wydajność, ponieważ każde dodatkowe wywołanie funkcji doda trochę narzutów.
Istnieją empiryczne sposoby na to również. Przychodzą mi na myśl moduły 'timeit' i' dis'. Czasami warto przetestować rzeczy dla siebie. –