:: Не фоксом единым
Python - параметры по-умолчанию
S-type

Сообщений: 2969
Дата регистрации: 24.04.2004
Читая про Python наткнулся на habrahabr.ru вот на такой пример:

def lister(lst = []):
lst.append([1, 2, 3]) # добавить в список элементы
print(lst)
lister() # [[1, 2, 3]]
lister() # [[1, 2, 3], [1, 2, 3]]
lister() # [[1, 2, 3], [1, 2, 3], [1, 2, 3]]

Проверил, действительно - Python работает именно так. Это несколько не укладывается в рамки привычного опыта. Например, в том же JavaScript всё работает так, как надо:

function lister(lst=[]){
lst.push([1, 2, 3])
alert(lst)
}
lister() // 1, 2, 3
lister() // 1, 2, 3
lister() // 1, 2, 3

Автор приводит аргументацию такого поведения:

Цитата:
проблема тут в том, что переменная lst будет ассоциирована с пустым списком один раз, и между вызовами будет сохранять свое значение.

В общем - взорвало мозг. Коллеги - есть какие то соображения, почему Python ведёт себя именно так?

P.S. Пример на VFP придумать не смог.
Ratings: 0 negative/0 positive
Re: Python - параметры по-умолчанию
S-type

Сообщений: 2969
Дата регистрации: 24.04.2004
Объяснение автора абсолютно не понятно. Например, если в Python-е заменить список на строку, получается "как надо"

def lister(lst = ""):
lst+="1, 2, 3"
print(lst)
lister() # 1, 2, 3
lister() # 1, 2, 3
lister() # 1, 2, 3
Ratings: 0 negative/0 positive
Re: Python - параметры по-умолчанию
Igor Korolyov
Автор

Сообщений: 34580
Дата регистрации: 28.05.2002
Там в комментах объясняется.
Строка - immutable объект, а список - нет. Поэтому если список УЖЕ ЕСТЬ, то он не "обнулится" при присвоении ему [] а строка - будет пересоздана.

На вопрос "почему" искать ответ бессмысленно. Так сделан интерпретатор. Вот почему в фоксе по умолчанию все переменные private и видны "абы где" ниже по стеку вызовов? И почему нет команды объявления private переменной (только при помощи "присвоения значения" можно её объявить), тогда как есть явные команды объявления и глобальных и локальных переменных Ответ тут один - by design


------------------
WBR, Igor
Ratings: 0 negative/0 positive
Re: Python - параметры по-умолчанию
S-type

Сообщений: 2969
Дата регистрации: 24.04.2004
В общем, как в комментах написал один товарищ:

Цитата:
Прочитал про дефолтные параметры интереса ради, ой ну и жуть это ваш питон. Можно прострелить себе ногу совершенно неожиданным способом!

Если что - мне для работы Python не нужен, ни один из моих знакомых на Python-е ни чего не ваяет. Это так, для расширения кругозора.
Ratings: 0 negative/0 positive
Re: Python - параметры по-умолчанию
Simple777

Сообщений: 33855
Дата регистрации: 05.11.2006
При расширении кругозора границы незнания также расширяются...
Ratings: 0 negative/0 positive
Re: Python - параметры по-умолчанию
S-type

Сообщений: 2969
Дата регистрации: 24.04.2004
Igor Korolyov
Строка - immutable объект, а список - нет. Поэтому если список УЖЕ ЕСТЬ, то он не "обнулится" при присвоении ему [] а строка - будет пересоздана.

Если сделать:

lst = []
lst.append([1, 2, 3]) # [[1, 2, 3]]
print(lst)
lst = []
lst.append([1, 2, 3]) # [[1, 2, 3]]
print(lst)

Т.е. если присвоить уже существующему списку [] он вполне себе обнуляется. Т.е. проблема именно в реализации интерпретатора. Что ж. Язык этот "динамично развивающийся", может будет ещё версия 4, обратно не совместимая с 3



Исправлено 1 раз(а). Последнее : S-type, 05.02.17 19:55
Ratings: 0 negative/0 positive
Re: Python - параметры по-умолчанию
S-type

Сообщений: 2969
Дата регистрации: 24.04.2004
Кстати, на счёт "расширения кругозора". До создания примера на JavaScript попытался создать пример на C#, и обнаружил - не могу! При указании:

static void lister(List<int> lst=new List<int>())
{
}

Вижу:

Visual Studio
Значение параметра по умолчанию для "lst" должно быть константой времени компиляции.

Действительно, это ведь компилятор, а не интерпретатор При этом понимаю, что для списков нет инициализирующего выражения. Т.е. для массива можно вместо:


string[] seasons = new string[4] { "зима", "весна", "лето", "осень" };

указать

string[] seasons = { "зима", "весна", "лето", "осень" };

Для списка есть:


List<int> numbers = new List<int>() { 1, 2, 3, 45 };

Но,

List<int> numbers2 = { 1, 2, 3, 45 };

выдаёт ошибку. Нет такого "упрощённого" (сладкого) выражения?

И ещё вопрос. Если параметр типа список (List), как для него задать "значение по умолчанию" отличное от Null?



Исправлено 1 раз(а). Последнее : S-type, 05.02.17 21:40
Ratings: 0 negative/0 positive
Re: Python - параметры по-умолчанию
Igor Korolyov
Автор

Сообщений: 34580
Дата регистрации: 28.05.2002
"Параметры по умолчанию" в C# могут быть либо константой (включая "значения" из перечислений), либо "пустым" ValueType вида new ... или же default().
При том что на самом деле эта синтаксическая конструкция лишь хинт для компилятора - он подставит в точке вызова эти самые значения в команду вызова метода.
Инициализирующие выражения тут совершенно не при чём. Сделать "параметром со значением по умолчанию" string[] нельзя так же как и List<string>.


------------------
WBR, Igor
Ratings: 0 negative/0 positive


Извините, только зарегистрированные пользователи могут оставлять сообщения в этом форуме.

On-line: 7 (Гостей: 7)

© 2000-2024 Fox Club 
Яндекс.Метрика