2015-10-08 1 views
0

У меня проблема, которую трудно объяснить, потому что в ней много кода. Таким образом, это сводится к следующей проблеме.Область списка Python вне функции

Я пытаюсь получить доступ к списку ххх вне функции Foo, но я получаю неожиданные результаты. Может кто-нибудь объяснить, почему?

Вот моя функция, которую я создал, чтобы показать проблему:

def foo(xxx = []): 
    if len(xxx) == 5: 
     return xxx 
    xxx += [1] 
    foo() 
    return xxx 

Если я бегу

print foo() 

Я получаю

[1, 1, 1, 1, 1] 

чего я ожидал.

Но я хочу, чтобы список xxx был доступен за пределами foo. Таким образом, я делаю

xxx = [] 
print foo(xxx) 
print xxx 

Теперь я ожидаю получить список ххх быть

[1, 1, 1, 1, 1] 

но что я получаю ххх быть, это

[1] 

что я не ожидаю.

Может кто-нибудь объяснить, почему? И можно ли получить доступ к правильному xxx за пределами foo без доступа к нему через выход функции foo? Причина, по которой я хочу это сделать, заключается в том, что в моем фактическом коде я возвращаю что-то другое, кроме как в своей функции foo и вносит изменения в xxx, который я хочу увидеть после того, как выполнен foo. Я могу сделать функцию также возвращать xxx каждый раз, но это сделает мой код излишне громоздким. Но я не уверен, что я компрометирую качество кода. Я не знаю. Пожалуйста, предложите, какой из когда-либо способ является лучшим.

Благодаря

+0

Комментарий устаревший Комментарий: – Hammerite

+0

Передача аргумента заменяет аргумент по умолчанию. Поэтому он будет с радостью изменять другой «список» при условии (и что «список» будет изменен, даже если он не будет возвращен), в противном случае он изменяет общий «список», используемый по умолчанию (к которому невозможно получить доступ, как правило, без его возврата). – ShadowRanger

+0

Просто боковое примечание (это не имеет ничего общего с вашим вопросом): старайтесь избегать изменчивых аргументов по умолчанию. Их поведение противоречит интуиции, и люди, использующие ваш код, могут получить неожиданные результаты. –

ответ

3
xxx = [] 
print foo(xxx) 
print xxx 

В этом коде вы звоните foo() со списком, созданной за пределами функции, называется xxx. Но внутри функции вы возвращаете вызов foo() без параметров, поэтому он изменяет список, созданный во время определения функции, выражением для значения аргумента по умолчанию. (Важно отметить, что это тот же список каждый раз, когда вы вызываете функцию без ввода значения для этого аргумента.)

Сравнит то, что происходит, когда вы определяете foo как это вместо:

def foo(xxx = None): 
    if xxx is None: 
     xxx = [] 
    if len(xxx) == 5: 
     return xxx 
    xxx += [1] 
    foo() 
    return xxx 

...и что происходит, когда вы определяете это следующим образом:

def foo(xxx = None): 
    if xxx is None: 
     xxx = [] 
    if len(xxx) == 5: 
     return xxx 
    xxx += [1] 
    foo(xxx) 
    return xxx 
+0

Второй код, который вы упомянули, решил мою проблему. Но попытка понять разницу между всеми тремя - это крутить мой разум. – Lokesh

+0

Грубо говоря, когда вы пишете foo (xxx = []), значение xxx инициализируется на уровне модуля и делится между всеми вызовами функции - не создается каждый раз, когда вы совершаете вызов. Об этом в Интернете и в StackOverflow есть много информации. –