2013-04-16 8 views
24

Spędziłem ostatnie kilka godzin czytając tutaj i gdzie indziej, a także eksperymentując, ale tak naprawdę nie rozumiem tego, co na pewno jest bardzo podstawową koncepcją: przekazywanie wartości (jako zmienne) pomiędzy różnymi funkcjami.Python: Przekazywanie zmiennych między funkcjami

Na przykład przypisać całą masę wartości do listy w jednej funkcji, a następnie chcą wykorzystać tę listę w innej funkcji później:

list = [] 

def defineAList(): 
    list = ['1','2','3'] 
    print "For checking purposes: in defineAList, list is",list 
    return list 

def useTheList(list): 
    print "For checking purposes: in useTheList, list is",list 

def main(): 
    defineAList() 
    useTheList(list) 

main() 

podstawie mojego zrozumienia, co funkcja argumenty zrobić, Spodziewamy się, że będzie to robić:

  1. Zainicjuj "listę" jako pustą listę; zadzwoń do głównego (przynajmniej, wiem, że mam prawo ...)
  2. W ramach defineAList(), przypisz pewne wartości do listy; następnie prześlij nową listę z powrotem do głównej()
  3. W obrębie głównej(), użyj wywołaniaTheList (lista)
  4. Ponieważ "lista" jest zawarta w parametrach funkcji UseTheList, oczekiwałbym, że użycieTheList będzie teraz używać tej listy jak zdefiniowano przez defineAList(), NIE pustą listę zdefiniowaną przed wywołaniem głównego.

Jednak jest to oczywiście błędne zrozumienie. Moje wyjście jest:

For checking purposes: in defineAList, list is ['1', '2', '3'] 
For checking purposes: in useTheList, list is [] 

Tak, ponieważ „powrotu” oczywiście nie robi tego, co myślę, że to robi, a przynajmniej nie robi to tak, myślę, że powinna ... co to właściwie zrobić? Czy mógłbyś mi pokazać, używając tego przykładu, co musiałbym zrobić, aby wziąć listę od defineAList() i użyć jej w useTheList()? Zaczynam rozumieć rzeczy lepiej, gdy widzę, że tak się dzieje, ale wiele przykładów prawidłowego przekazywania argumentów, które widziałem, używa również kodu, którego jeszcze nie znam, i w trakcie ustalania, co się dzieje, Naprawdę nie rozumiem tej koncepcji. Używam 2.7.

ETA - w przeszłości, zadając podobne pytanie, zasugerowano, że używam zmiennej globalnej zamiast tylko lokalnych. Jeśli będzie to miało znaczenie również tutaj - dla celów zajęć, które biorę, nie możemy używać globali.

Dziękujemy!

Odpowiedz

26

To jest to, co się rzeczywiście dzieje:

global_list = [] 

def defineAList(): 
    local_list = ['1','2','3'] 
    print "For checking purposes: in defineAList, list is", local_list 
    return local_list 

def useTheList(passed_list): 
    print "For checking purposes: in useTheList, list is", passed_list 

def main(): 
    # returned list is ignored 
    returned_list = defineAList() 

    # passed_list inside useTheList is set to global_list 
    useTheList(global_list) 

main() 

To jest to, co chcesz:

def defineAList(): 
    local_list = ['1','2','3'] 
    print "For checking purposes: in defineAList, list is", local_list 
    return local_list 

def useTheList(passed_list): 
    print "For checking purposes: in useTheList, list is", passed_list 

def main(): 
    # returned list is ignored 
    returned_list = defineAList() 

    # passed_list inside useTheList is set to what is returned from defineAList 
    useTheList(returned_list) 

main() 

Można nawet pominąć tymczasowy returned_list i przechodzą zwracanej wartości bezpośrednio do useTheList:

def main(): 
    # passed_list inside useTheList is set to what is returned from defineAList 
    useTheList(defineAList()) 
+0

Dziękujemy za szczegółowe wyjaśnienie również! Wiedziałem, że brakuje mi czegoś podstawowego. :) – user2113818

+7

Proszę nie nazwać rzeczy 'list', tracisz możliwość wywołania wbudowanej' listy' :) –

+1

Nie robię tego, kiedy piszę coś, co zamierzam uruchomić w jakimś celu! – user2113818

7

Po prostu brakuje jednego krytycznego kroku. Musisz jawnie przekazać wartość zwracaną do drugiej funkcji.

def main(): 
    l = defineAList() 
    useTheList(l) 

Alternatywnie:

def main(): 
    useTheList(defineAList()) 

Albo (choć nie powinno się tego robić Mogłoby się wydawać, miły w pierwszym, ale globalne tylko żal bo na dłuższą metę!.):

l = [] 

def defineAList(): 
    global l 
    l.extend(['1','2','3']) 

def main(): 
    global l 
    defineAList() 
    useTheList(l) 

Funkcja zwraca wartość, ale nie tworzy symbolu w globalnej przestrzeni nazw, jak zakłada twój kod. Musisz w rzeczywistości uchwycić wartość zwracaną w zakresie wywoływania, a następnie użyć jej do kolejnych operacji.

+0

Thank you-Rozumiem, że podałeś nie tylko przykład, ale wyjaśnienie dlaczego to działa w ten sposób. – user2113818

3

Twój powrót jest bezużyteczny, jeśli nie przypisywać to

list=defineAList() 
1

return zwraca wartość. Nie ma znaczenia, jakie imię dałeś tej wartości.Zwrócenie go po prostu "przepuszcza", aby coś innego mogło z niego korzystać. Jeśli chcesz go używać, trzeba chwycić go od zewnątrz:

lst = defineAList() 
useTheList(lst) 

Wracając list od wewnątrz defineAList nie oznacza „uczynić go więc cała reszta programu można używać tej zmiennej”. Oznacza to "przekazanie tej zmiennej i dać reszcie programu jedną szansę, aby ją pobrać i użyć". Musisz przypisać tę wartość do czegoś spoza funkcji, aby móc z niej skorzystać. Z tego powodu nie ma potrzeby definiowania listy z wyprzedzeniem za pomocą list = []. Wewnątrz defineAList tworzysz nową listę i zwraca ją; ta lista nie ma związku z tą, którą zdefiniowałeś na początku z list = [].

Nawiasem mówiąc, zmieniłem nazwę zmiennej z list na lst. Nie jest dobrym pomysłem użycie list jako nazwy zmiennej, ponieważ jest to już nazwa wbudowanego typu Pythona. Jeśli utworzysz własną zmienną o nazwie list, utracisz dostęp do wbudowanej zmiennej.

2

Zapoznaj się z pojęciem przestrzeni nazw. Kiedy przypisujesz zmienną do funkcji, przypisujesz ją tylko w przestrzeni nazw tej funkcji. Ale wyraźnie chcesz używać go między wszystkimi funkcjami.

def defineAList(): 
    #list = ['1','2','3'] this creates a new list, named list in the current namespace. 
    #same name, different list! 

    list.extend['1', '2', '3', '4'] #this uses a method of the existing list, which is in an outer namespace 
    print "For checking purposes: in defineAList, list is",list 
    return list 

Alternatywnie, można przekazać je wokół:

def main(): 
    new_list = defineAList() 
    useTheList(new_list) 
1

przechodzącej zmiennej z jednej funkcji jako argument do innych funkcji można zrobić tak

definiować funkcje jak ten

def function1(): 
global a 
a=input("Enter any number\t") 

def function2(argument): 
print ("this is the entered number - ",argument) 

wywoływać funkcje takie jak ta

function1() 
function2(a) 
+0

Wcięcie jest dość nietypowe, które powinno zostać naprawione jako pierwsze. Po drugie, ponieważ określasz 'global a', nie ma potrzeby stosowania instrukcji' return' w 'function1()'. Jest w gruncie rzeczy zły gust używać zmiennych "globalnych" w ogóle, ale zupełnie nieuzasadnionych w tak prostej aplikacji. Cf. [to] (http://stackoverflow.com/questions/19158339/why-are-global-variables-evil). –

+0

@ N.Wouda jak mogę wykonać taką operację bez użycia globalnego? –

+1

'def function1(): return input (" Wprowadź dowolną liczbę \ t ")'. Następnie 'a = funkcja1()' i 'funkcja2 (a)'. Oczywiście powinieneś zastosować odpowiednie formatowanie tego kodu, ale nie mogę tego osiągnąć w komentarzu. –