2012-12-31 9 views
6

W Pythonie 2.7.1 próbuję podać listę komunikatów jako pierwszy argument, a listę kolorów jako drugi argument. Chcę, aby drugi argument domyślnie zawierał listę białych, jeśli nie została podana. To jest droga Próbowałem to zrobić:Zrozumienie listy w argumentach funkcji

def multicolor_message(msgs, colors=[libtcod.white for x in len(msgs)]): 
#function body 

libtcod.white jest częścią biblioteki używam i jest w żaden sposób nie powodując żadnych problemów. Kompilator mówi, że zmienna msgs nie jest zdefiniowana. Oczywiście zmienna msgs nie istnieje w tym zakresie, ale muszę utworzyć listę o odpowiedniej długości i przypisać ją do colors. Jaki jest najczystszy sposób na zrobienie tego?

+0

należy podać wiadomość StackTrace/błędzie –

+1

zainicjować wartości niezdefiniowanych w organizmie zamiast tego funkcji lub wywołaj ją za pomocą funkcji otoki, która robi to za ciebie. – tripleee

+0

@InbarRose W tym przypadku stos śledzenia nie był konieczny, aby zobaczyć, co jest nie tak – piokuc

Odpowiedz

6

zrobiłbym to tak:

def multicolor_message(msgs, colors=None): 
    if colors is None: 
    colors=[libtcod.white for x in len(msgs)] 
+4

Powodem takiego postępowania jest to, że nie można odwoływać się do innych argumentów o tej samej funkcji w wartościach domyślnych. Wartości domyślne są określane w zakresie definicji funkcji, a same argumenty istnieją tylko po wywołaniu funkcji. –

+0

@MattiVirkkunen Zgadza się. – piokuc

+2

Innym ważnym powodem jest to, że [zmienne argumenty domyślne] (http://stackoverflow.com/q/1132941/395760) rzadko robią to, co chcesz. – delnan

4

To niemożliwe jest Python, jako domyślne argumenty funkcji są wykonywane w momencie definicji funkcji i zmienna msgs nie będzie dostępna dopóki funkcja jest wywoływana.

Z docs: Wartości parametrów

domyślne są oceniane gdy definicja funkcji jest wykonywany. Oznacza to, że wyrażenie jest obliczane jednorazowo, gdy zdefiniowana jest funkcja i że dla każdego połączenia używana jest ta sama wartość "wstępnie obliczona" ( ). Jest to szczególnie ważne, aby zrozumieć, kiedy domyślny parametr jest zmiennym obiektem, takim jak lista lub słownik: , jeśli funkcja modyfikuje obiekt (np. Poprzez dołączenie elementu do listy ), zmienia się domyślna wartość . Zasadniczo nie jest to zamierzone. Sposobem na to jest użycie None jako domyślny, i wyraźnie przetestować go w ciele funkcji, np:

def whats_on_the_telly(penguin=None): 
    if penguin is None: 
     penguin = [] 
    penguin.append("property of the zoo") 
    return penguin 
+0

Nie w czasie kompilacji. W czasie definiowania funkcji. Różnica ma znaczenie dla funkcji zagnieżdżonych lub gdy w wyrażeniach używane są nazwy na poziomie modułów. – delnan