Отмеченное против неизмененного поведения объекта в функциях python [duplicate]

Есть несколько хороших регулярных выражений для замены HTML с помощью BBCode здесь . Обратите внимание на то, что он не пытается полностью разобрать HTML, просто для того, чтобы его дезинфицировать. Вероятно, он может убить теги, которые его простой «парсер» не может понять.

Например:

$store =~ s/http:/http:\/\//gi;
$store =~ s/https:/https:\/\//gi;
$baseurl = $store;

if (!$query->param("ascii")) {
    $html =~ s/\s\s+/\n/gi;
    $html =~ s/(.*?)<\/pre>/\[code]$2\[\/code]/sgmi;
}

$html =~ s/\n//gi;
$html =~ s/\r\r//gi;
$html =~ s/$baseurl//gi;
$html =~ s/(.*?)<\/h[1-7]>/\n\[b]$2\[\/b]\n/sgmi;
$html =~ s/

/\n\n/gi; $html =~ s//\n/gi; $html =~ s/(.*?)<\/textarea>/\[code]$2\[\/code]/sgmi; $html =~ s/(.*?)<\/b>/\[b]$1\[\/b]/gi; $html =~ s/(.*?)<\/i>/\[i]$1\[\/i]/gi; $html =~ s/(.*?)<\/u>/\[u]$1\[\/u]/gi; $html =~ s/(.*?)<\/em>/\[i]$1\[\/i]/gi; $html =~ s/(.*?)<\/strong>/\[b]$1\[\/b]/gi; $html =~ s/(.*?)<\/cite>/\[i]$1\[\/i]/gi; $html =~ s/(.*?)<\/font>/\[color=$1]$2\[\/color]/sgmi; $html =~ s/(.*?)<\/font>/\[color=$1]$2\[\/color]/sgmi; $html =~ s///gi; $html =~ s/(.*?)<\/li>/\[\*]$2/gi; $html =~ s//\[list]/gi; $html =~ s/<\/ul>/\[\/list]/gi; $html =~ s/

/\n/gi; $html =~ s/<\/div>/\n/gi; $html =~ s// /gi; $html =~ s//\n/gi; $html =~ s//\[img]$baseurl\/$2\[\/img]/gi; $html =~ s/(.*?)<\/a>/\[url=$baseurl\/$2]$4\[\/url]/gi; $html =~ s/\[url=$baseurl\/http:\/\/(.*?)](.*?)\[\/url]/\[url=http:\/\/$1]$2\[\/url]/gi; $html =~ s/\[img]$baseurl\/http:\/\/(.*?)\[\/img]/\[img]http:\/\/$1\[\/img]/gi; $html =~ s/(.*?)<\/head>//sgmi; $html =~ s/(.*?)<\/object>//sgmi; $html =~ s/(.*?)<\/script>//sgmi; $html =~ s/(.*?)<\/style>//sgmi; $html =~ s/(.*?)<\/title>//sgmi; $html =~ s/<!--(.*?)-->/\n/sgmi; $html =~ s/\/\//\//gi; $html =~ s/http:\//http:\/\//gi; $html =~ s/https:\//https:\/\//gi; $html =~ s/<(?:[^>'"]*|(['"]).*?\1)*>//gsi; $html =~ s/\r\r//gi; $html =~ s/\[img]\//\[img]/gi; $html =~ s/\[url=\//\[url=/gi; </code></pre></p> </div> <div class="votes-question"> <div class="vote-count" itemprop="upvoteCount">2125</div><i class="fa fa-thumbs-o-up"></i> </div> <div class="tags"> <a href="/questions/tagged/python" class="tag" title="python" rel="tag">python</a> <a href="/questions/tagged/function" class="tag" title="function" rel="tag">function</a> <a href="/questions/tagged/immutability" class="tag" title="immutability" rel="tag">immutability</a> <a href="/questions/tagged/mutable" class="tag" title="mutable" rel="tag">mutable</a> </div> <div class="clearfix"></div> <div class="action-time"> задан Matt <span title="29 January 2017 в 01:29 ">29 January 2017 в 01:29 </span> </div> <a class="s-link" href="/questions/2365/otmechennoe-protiv-neizmenennogo-povedeniya-ob-ekta-v-funkciyax-python-duplicate" title="поделиться">поделиться</a> </div> </div> <div style="height:100px;margin:10px 0px;" class=""> <script async src="//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script> <!-- siteask before post --> <ins class="adsbygoogle" style="display:block;height:100px" data-ad-client="ca-pub-2355906945027976" data-ad-slot="" data-ad-format="auto"></ins> <script> (adsbygoogle = window.adsbygoogle || []).push({}); </script> </div> <div class="answers" id="answers"> <h2 class="pull-left"><span itemprop="answerCount">30</span> ответов</h2> <div class="clearfix"></div> <div class="answer-pager"> <div class="pagination"> </div> </div> <div class="answer accepted" id="14125" itemscope="" itemtype="http://schema.org/Answer" itemprop="acceptedAnswer"> <div class="answer-row"> <div class="answer-text"> <div class="description" itemprop="text"> <p> На самом деле, это не ошибка дизайна, и это происходит не из-за внутренних компонентов, а из-за производительности. Это происходит просто из-за того, что функции в Python являются первоклассными объектами, а не только частью кода. </p> <p> Как только вы додумаетесь до этого, тогда это полностью имеет смысл: функция - объект, оцениваемый по его определению; параметры по умолчанию являются «данными-членами», и поэтому их состояние может меняться от одного вызова к другому - точно так же, как и к любому другому объекту. </p> <p> В любом случае Effbot имеет очень хорошее объяснение причин это поведение в <a href="/go.php?url=http%3a%2f%2feffbot.org%2fzone%2fdefault-values.htm" rel="noreferrer"> Значения параметров по умолчанию в Python </a>. Я нашел это очень ясным, и я действительно предлагаю прочитать его, чтобы лучше узнать, как работают объекты функций. </p> </div> <div class="votes-answer green"> <div class="vote-count" itemprop="upvoteCount">1355</div><i class="fa fa-thumbs-o-up"></i> </div> <div class="clearfix"></div> <div class="action-time"> ответ дан Roberto Liffredo <span title="15 August 2018 в 21:10 ">15 August 2018 в 21:10 </span> </div> <a class="s-link" href="/questions/2365/otmechennoe-protiv-neizmenennogo-povedeniya-ob-ekta-v-funkciyax-python-duplicate#584" title="поделиться">поделиться</a> </div> <div class="post-layout--right"> <div id="comments-14125"> <ul class="comments-list js-comments-list" data-remaining-comments-count="0" data-canpost="false" data-cansee="true" data-comments-unavailable="false" data-addlink-disabled="true"> <li id="comment-22565" class="comment js-comment " data-comment-id="22565"> <div class="js-comment-actions comment-actions"> <div class="comment-score"> <span title="номер полезного комментария для вопроса" class="cool">1</span> </div> </div> <div class="comment-text js-comment-text-and-form"> <div style="display: block;" class="comment-body"> <span class="comment-copy">Для всех, кто читает вышеприведенный ответ, я настоятельно рекомендую вам потратить время на ознакомление с связанной статьей Effbot. Как и вся другая полезная информация, очень важно знать, как эта языковая функция может использоваться для кэширования результатов / memoisation! </span> – <span class="comment-user">Cam Jackson</span> <span class="comment-date" dir="ltr"><a class="comment-link" href="#comment14125_22565"><span title="14 October 2011 в 01:05 " class="relativetime-clean">14 October 2011 в 01:05 </span></a></span> </div> </div> </li> <li id="comment-22566" class="comment js-comment " data-comment-id="22566"> <div class="js-comment-actions comment-actions"> <div class="comment-score"> <span title="номер полезного комментария для вопроса" class="cool">2</span> </div> </div> <div class="comment-text js-comment-text-and-form"> <div style="display: block;" class="comment-body"> <span class="comment-copy">Даже если это объект первого класса, можно все же представить конструкцию, в которой <i> code </ i> для каждого значения по умолчанию сохраняется вместе с объектом и переоценивается каждый раз при вызове функции. Я не говорю, что было бы лучше, просто функции, являющиеся первоклассными объектами, не полностью исключают его. </span> – <span class="comment-user">gerrit</span> <span class="comment-date" dir="ltr"><a class="comment-link" href="#comment14125_22566"><span title="11 January 2013 в 12:55 " class="relativetime-clean">11 January 2013 в 12:55 </span></a></span> </div> </div> </li> <li id="comment-22567" class="comment js-comment " data-comment-id="22567"> <div class="js-comment-actions comment-actions"> <div class="comment-score"> <span title="номер полезного комментария для вопроса" class="cool">3</span> </div> </div> <div class="comment-text js-comment-text-and-form"> <div style="display: block;" class="comment-body"> <span class="comment-copy">Извините, но все, что считается «Самый большой WTF в Python», <b> наиболее определенно является дефектом дизайна </b>. Это источник ошибок для <i> each </ i> в какой-то момент, потому что никто не ожидает этого поведения сначала, а это значит, что он не должен был быть разработан таким образом. Меня не волнует, какие обручи им пришлось перепрыгнуть, они <b> должны </b> спроектировать Python, так что аргументы по умолчанию не статичны. </span> – <span class="comment-user">BlueRaja - Danny Pflughoeft</span> <span class="comment-date" dir="ltr"><a class="comment-link" href="#comment14125_22567"><span title="7 June 2013 в 22:28 " class="relativetime-clean">7 June 2013 в 22:28 </span></a></span> </div> </div> </li> <li id="comment-22568" class="comment js-comment " data-comment-id="22568"> <div class="js-comment-actions comment-actions"> <div class="comment-score"> <span title="номер полезного комментария для вопроса" class="cool">4</span> </div> </div> <div class="comment-text js-comment-text-and-form"> <div style="display: block;" class="comment-body"> <span class="comment-copy">Независимо от того, является ли это дефектом дизайна, ваш ответ, по-видимому, подразумевает, что такое поведение является каким-то необходимым, естественным и очевидным, учитывая, что функции являются первоклассными объектами, и это просто не так. У Python есть замыкания. Если вы замените аргумент по умолчанию назначением в первой строке функции, он вычисляет выражение каждого вызова (потенциально используя имена, объявленные в охватывающей области). Нет никакой причины, что было бы невозможно или разумно, чтобы аргументы по умолчанию оценивались каждый раз, когда функция вызывается точно так же. </span> – <span class="comment-user">Mark Amery</span> <span class="comment-date" dir="ltr"><a class="comment-link" href="#comment14125_22568"><span title="9 January 2014 в 00:16 " class="relativetime-clean">9 January 2014 в 00:16 </span></a></span> </div> </div> </li> <li id="comment-22569" class="comment js-comment " data-comment-id="22569"> <div class="js-comment-actions comment-actions"> <div class="comment-score"> <span title="номер полезного комментария для вопроса" class="cool">5</span> </div> </div> <div class="comment-text js-comment-text-and-form"> <div style="display: block;" class="comment-body"> <span class="comment-copy">Дизайн не следует непосредственно из <code>functions are objects</code>. В вашей парадигме предложение будет состоять в том, чтобы реализовать значения функций по умолчанию как свойства, а не атрибуты. </span> – <span class="comment-user">bukzor</span> <span class="comment-date" dir="ltr"><a class="comment-link" href="#comment14125_22569"><span title="3 May 2014 в 21:46 " class="relativetime-clean">3 May 2014 в 21:46 </span></a></span> </div> </div> </li> </ul> </div> </div> </div> </div> <div class="answer" id="14101" itemscope="" itemtype="http://schema.org/Answer"> <div class="answer-row"> <div class="answer-text"> <div class="description" itemprop="text"> <p> Я ничего не знаю о внутренних интерпретаторах Python-интерпретатора (и я тоже не являюсь экспертом в компиляторах и интерпретаторах), поэтому не обвиняйте меня, если я предлагаю что-либо недоступное или невозможное. </p> <p> При условии, что python объекты меняются. Я думаю, что это следует учитывать при разработке аргументов аргументов по умолчанию. Когда вы создаете экземпляр списка: </p> <pre><code>a = [] </code></pre> <p> вы ожидаете получить новый список, на который ссылается <em> a </em>. </p> <p> Почему a = [] в </p> <pre><code>def x(a=[]): </code></pre> <p> создать новый список по определению функции, а не по вызову? Это точно так же, как вы спрашиваете: «Если пользователь не предоставляет аргумент, тогда <em> создает экземпляр </em> нового списка и использует его, как если бы он был создан вызывающим». Я думаю, что это неоднозначно: </p> <pre><code>def x(a=datetime.datetime.now()): </code></pre> <p> пользователь, вы хотите <em> a </em> по умолчанию использовать дату и время, соответствующее тому, когда вы определяете или выполняете <em> x </em>? В этом случае, как и в предыдущем, я буду придерживаться такого же поведения, как если бы аргумент по умолчанию «назначение» был первой инструкцией функции (datetime.now (), вызванной вызовом функции). С другой стороны, если пользователь хотел отобразить время отображения, он мог бы написать: </p> <pre><code>b = datetime.datetime.now() def x(a=b): </code></pre> <p> Я знаю, я знаю: это закрытие. В качестве альтернативы Python может предоставить ключевое слово для привязки определения времени: </p> <pre><code>def x(static a=b): </code></pre> </div> <div class="votes-answer green"> <div class="vote-count" itemprop="upvoteCount">97</div><i class="fa fa-thumbs-o-up"></i> </div> <div class="clearfix"></div> <div class="action-time"> ответ дан 101 <span title="15 August 2018 в 21:10 ">15 August 2018 в 21:10 </span> </div> <a class="s-link" href="/questions/2365/otmechennoe-protiv-neizmenennogo-povedeniya-ob-ekta-v-funkciyax-python-duplicate#584" title="поделиться">поделиться</a> </div> <div class="post-layout--right"> <div id="comments-14101"> <ul class="comments-list js-comments-list" data-remaining-comments-count="0" data-canpost="false" data-cansee="true" data-comments-unavailable="false" data-addlink-disabled="true"> <li id="comment-22496" class="comment js-comment " data-comment-id="22496"> <div class="js-comment-actions comment-actions"> <div class="comment-score"> <span title="номер полезного комментария для вопроса" class="cool">1</span> </div> </div> <div class="comment-text js-comment-text-and-form"> <div style="display: block;" class="comment-body"> <span class="comment-copy">Вы можете сделать: def x (a = None): И тогда, если a есть None, установите a = datetime.datetime.now () </span> – <span class="comment-user">Anon</span> <span class="comment-date" dir="ltr"><a class="comment-link" href="#comment14101_22496"><span title="16 July 2009 в 01:18 " class="relativetime-clean">16 July 2009 в 01:18 </span></a></span> </div> </div> </li> <li id="comment-22497" class="comment js-comment " data-comment-id="22497"> <div class="js-comment-actions comment-actions"> <div class="comment-score"> <span title="номер полезного комментария для вопроса" class="cool">2</span> </div> </div> <div class="comment-text js-comment-text-and-form"> <div style="display: block;" class="comment-body"> <span class="comment-copy">Я знаю, это был просто пример, объясняющий, почему я предпочитаю привязку времени исполнения. </span> – <span class="comment-user">Utaal</span> <span class="comment-date" dir="ltr"><a class="comment-link" href="#comment14101_22497"><span title="16 July 2009 в 10:01 " class="relativetime-clean">16 July 2009 в 10:01 </span></a></span> </div> </div> </li> <li id="comment-22498" class="comment js-comment " data-comment-id="22498"> <div class="js-comment-actions comment-actions"> <div class="comment-score"> <span title="номер полезного комментария для вопроса" class="cool">3</span> </div> </div> <div class="comment-text js-comment-text-and-form"> <div style="display: block;" class="comment-body"> <span class="comment-copy">Спасибо тебе за это. Я не мог сказать, почему это раздражает меня до конца. Вы сделали это красиво с минимальным пухом и путаницей. Как кто-то из системного программирования на C ++, а иногда и наивно "перевод" языковые особенности, этот ложный друг пинал меня в мягкой голове большой раз, точно так же, как атрибуты класса. Я понимаю, почему все так, но я не могу не любить, независимо от того, что из этого может получиться. По крайней мере, это настолько противоречит моему опыту, что я, вероятно (надеюсь) никогда не забуду это ... </span> – <span class="comment-user">AndreasT</span> <span class="comment-date" dir="ltr"><a class="comment-link" href="#comment14101_22498"><span title="22 April 2011 в 10:33 " class="relativetime-clean">22 April 2011 в 10:33 </span></a></span> </div> </div> </li> <li id="comment-22499" class="comment js-comment " data-comment-id="22499"> <div class="js-comment-actions comment-actions"> <div class="comment-score"> <span title="номер полезного комментария для вопроса" class="cool">4</span> </div> </div> <div class="comment-text js-comment-text-and-form"> <div style="display: block;" class="comment-body"> <span class="comment-copy">@Andreas, как только вы используете Python достаточно долго, вы начинаете видеть, насколько логично, чтобы Python интерпретировал вещи как атрибуты класса так, как это делается, - только из-за особых особенностей и ограничений таких языков, как C ++ (и Java, и C # ...), что смысл содержимого блока <code>class {}</code> интерпретироваться как принадлежащий <i> экземплярам </ i> :). Но когда классы являются первоклассными объектами, очевидно, что естественным является их содержимое (в памяти), чтобы отразить их содержимое (в коде). </span> – <span class="comment-user">Karl Knechtel</span> <span class="comment-date" dir="ltr"><a class="comment-link" href="#comment14101_22499"><span title="22 July 2011 в 20:55 " class="relativetime-clean">22 July 2011 в 20:55 </span></a></span> </div> </div> </li> <li id="comment-22500" class="comment js-comment " data-comment-id="22500"> <div class="js-comment-actions comment-actions"> <div class="comment-score"> <span title="номер полезного комментария для вопроса" class="cool">5</span> </div> </div> <div class="comment-text js-comment-text-and-form"> <div style="display: block;" class="comment-body"> <span class="comment-copy">Нормативная структура - это не причуда или ограничение в моей книге. Я знаю, что это может быть неуклюжим и уродливым, но вы можете назвать это «определением». чего-либо. Динамические языки кажутся мне анархистами: Конечно, все свободны, но вам нужна структура, чтобы заставить кого-то опорожнить мусор и проложить дорогу. Думаю, я стар ... :) </span> – <span class="comment-user">AndreasT</span> <span class="comment-date" dir="ltr"><a class="comment-link" href="#comment14101_22500"><span title="26 July 2011 в 09:54 " class="relativetime-clean">26 July 2011 в 09:54 </span></a></span> </div> </div> </li> </ul> </div> </div> </div> </div> <div class="answer" id="14102" itemscope="" itemtype="http://schema.org/Answer"> <div class="answer-row"> <div class="answer-text"> <div class="description" itemprop="text"> <h1> Python: Mutable Default Argument </h1> <p> Аргументы по умолчанию получают оценку во время компиляции функции в объект функции. При использовании этой функции, несколько раз с помощью этой функции, они являются и остаются одним и тем же объектом. </p> <p> Когда они изменяются, когда они мутируются (например, добавляя к нему элемент), они остаются мутированными по последовательным вызовам. </p> <p> Они остаются мутированными, потому что каждый раз они являются одним и тем же объектом . </p> <h2> Эквивалентный код: </h2> <p> Поскольку список связан с функцией, когда объект функции компилируется и инстанцируется, это: </p> <pre><code>def foo(mutable_default_argument=[]): # make a list the default argument """function that uses a list""" </code></pre> <p> почти точно эквивалентно этому: </p> <pre><code>_a_list = [] # create a list in the globals def foo(mutable_default_argument=_a_list): # make it the default argument """function that uses a list""" del _a_list # remove globals name binding </code></pre> <h2> Демонстрация </h2> <p> Вот демонстрация - вы можете проверить, что они являются одним и тем же объектом каждый раз, когда они ссылаются на </p> <ul> <li>, увидев, что список создан до того, как функция завершила компиляцию объекту функции, </li> <li>, заметив, что идентификатор один и тот же каждый раз, когда список ссылается, </li> <li>, наблюдая, что список остается, когда функция, которая его использует, называется второй раз, </li> <li>, наблюдая порядок, в котором вывод печатается из источника (который я удобно пронумеровал для вас): </li> </ul> <p> <code>example.py</code> </p> <pre><code>print('1. Global scope being evaluated') def create_list(): '''noisily create a list for usage as a kwarg''' l = [] print('3. list being created and returned, id: ' + str(id(l))) return l print('2. example_function about to be compiled to an object') def example_function(default_kwarg1=create_list()): print('appending "a" in default default_kwarg1') default_kwarg1.append("a") print('list with id: ' + str(id(default_kwarg1)) + ' - is now: ' + repr(default_kwarg1)) print('4. example_function compiled: ' + repr(example_function)) if __name__ == '__main__': print('5. calling example_function twice!:') example_function() example_function() </code></pre> <p> и работает это с <code>python example.py</code>: </p> <pre><code>1. Global scope being evaluated 2. example_function about to be compiled to an object 3. list being created and returned, id: 140502758808032 4. example_function compiled: <function example_function at 0x7fc9590905f0> 5. calling example_function twice!: appending "a" in default default_kwarg1 list with id: 140502758808032 - is now: ['a'] appending "a" in default default_kwarg1 list with id: 140502758808032 - is now: ['a', 'a'] </code></pre> <h2> Означает ли это нарушение принципа «Наименьшее удивление»? </h2> <p> Этот порядок выполнения часто путает новых пользователей Python. Если вы понимаете модель исполнения Python, это становится вполне ожидаемым. </p> <h2> Обычная инструкция для новых пользователей Python: </h2> <p> Но поэтому обычная инструкция для новых пользователей заключается в том, чтобы вместо этого создать свои аргументы по умолчанию: </p> <pre><code>def example_function_2(default_kwarg=None): if default_kwarg is None: default_kwarg = [] </code></pre> <p> Это использует None singleton как объект-дозор, чтобы сообщить функции, есть ли у нас аргумент, отличный от значения по умолчанию. Если мы не получаем никакого аргумента, то мы действительно хотим использовать новый пустой список <code>[]</code> в качестве значения по умолчанию. </p> <p> Как говорится в разделе <a href="/go.php?url=https%3a%2f%2fdocs.python.org%2ftutorial%2fcontrolflow.html%23default-argument-values" rel="noreferrer"> в разделе управления потоком </a>: </p> <blockquote> <p> Если вы не хотите, чтобы по умолчанию были разделены между последующими вызовами, вы можете написать такую ​​функцию, как это: </p> <pre><code>def f(a, L=None): if L is None: L = [] L.append(a) return L </code></pre> </blockquote> </div> <div class="votes-answer green"> <div class="vote-count" itemprop="upvoteCount">17</div><i class="fa fa-thumbs-o-up"></i> </div> <div class="clearfix"></div> <div class="action-time"> ответ дан Aaron Hall <span title="15 August 2018 в 21:10 ">15 August 2018 в 21:10 </span> </div> <a class="s-link" href="/questions/2365/otmechennoe-protiv-neizmenennogo-povedeniya-ob-ekta-v-funkciyax-python-duplicate#584" title="поделиться">поделиться</a> </div> <div class="post-layout--right"> <div id="comments-14102"> <ul class="comments-list js-comments-list" data-remaining-comments-count="0" data-canpost="false" data-cansee="true" data-comments-unavailable="false" data-addlink-disabled="true"> </ul> </div> </div> </div> </div> <div class="answer" id="14103" itemscope="" itemtype="http://schema.org/Answer"> <div class="answer-row"> <div class="answer-text"> <div class="description" itemprop="text"> <p> Я собираюсь продемонстрировать альтернативную структуру, чтобы передать значение списка по умолчанию функции (она одинаково хорошо работает со словарями). </p> <p> Поскольку другие подробно комментируют, параметр списка привязан к функции, когда она определена, а не когда она выполняется. Поскольку списки и словари изменяемы, любое изменение этого параметра влияет на другие вызовы этой функции. В результате последующие вызовы функции получат этот общий список, который может быть изменен любыми другими вызовами функции. Хуже того, два параметра используют общий параметр этой функции, в то же время не обращая внимания на изменения, сделанные другим. </p> <p> Неверный метод (возможно ...): </p> <pre><code>def foo(list_arg=[5]): return list_arg a = foo() a.append(6) >>> a [5, 6] b = foo() b.append(7) # The value of 6 appended to variable 'a' is now part of the list held by 'b'. >>> b [5, 6, 7] # Although 'a' is expecting to receive 6 (the last element it appended to the list), # it actually receives the last element appended to the shared list. # It thus receives the value 7 previously appended by 'b'. >>> a.pop() 7 </code></pre> <p> Вы можете убедиться, что это один и тот же объект, используя <code>id</code>: </p> <pre><code>>>> id(a) 5347866528 >>> id(b) 5347866528 </code></pre> <p> Per Brett Slatkin's «Эффективный Python: 59 конкретных способов записи лучшего Python», <em> Пункт 20: Использование <code>None</code> и Docstrings для указания динамических аргументов по умолчанию </em> (стр. 48) </p> <blockquote> <p> Соглашение о достижении желаемого результата в Python заключается в предоставлении значения по умолчанию <code>None</code> и документируйте фактическое поведение в docstring. </p> </ blockquote> <p> Эта реализация гарантирует, что каждый вызов функции либо получает список по умолчанию, либо список, переданный функции. </p> <p> Предпочтительный Метод: </p> <pre><code>def foo(list_arg=None): """ :param list_arg: A list of input values. If none provided, used a list with a default value of 5. """ if not list_arg: list_arg = [5] return list_arg a = foo() a.append(6) >>> a [5, 6] b = foo() b.append(7) >>> b [5, 7] c = foo([10]) c.append(11) >>> c [10, 11] </code></pre> <p> В «Неправильном методе» могут быть законные варианты использования, в соответствии с которыми программист предполагает, что параметр списка по умолчанию должен быть общим, но это скорее исключение, чем правило. </p> </div> <div class="votes-answer green"> <div class="vote-count" itemprop="upvoteCount">16</div><i class="fa fa-thumbs-o-up"></i> </div> <div class="clearfix"></div> <div class="action-time"> ответ дан Alexander <span title="15 August 2018 в 21:10 ">15 August 2018 в 21:10 </span> </div> <a class="s-link" href="/questions/2365/otmechennoe-protiv-neizmenennogo-povedeniya-ob-ekta-v-funkciyax-python-duplicate#584" title="поделиться">поделиться</a> </div> <div class="post-layout--right"> <div id="comments-14103"> <ul class="comments-list js-comments-list" data-remaining-comments-count="0" data-canpost="false" data-cansee="true" data-comments-unavailable="false" data-addlink-disabled="true"> </ul> </div> </div> </div> </div> <div class="answer" id="14104" itemscope="" itemtype="http://schema.org/Answer"> <div class="answer-row"> <div class="answer-text"> <div class="description" itemprop="text"> <p> Самый короткий ответ, вероятно, будет «определение - исполнение», поэтому весь аргумент не имеет строгой точки зрения. В качестве более надуманного примера вы можете привести следующее: </p> <pre><code>def a(): return [] def b(x=a()): print x </code></pre> <p>. Надеюсь, этого достаточно, чтобы показать, что не выполнять выражения аргументов по умолчанию во время выполнения инструкции <code>def</code> не просто или не работает, т. е. смысл, или и то, и другое. </p> <p> Я согласен с тем, что при попытке использовать конструкторы по умолчанию, это будет gotcha. </p> </div> <div class="votes-answer green"> <div class="vote-count" itemprop="upvoteCount">17</div><i class="fa fa-thumbs-o-up"></i> </div> <div class="clearfix"></div> <div class="action-time"> ответ дан Ashraf.Shk786 <span title="15 August 2018 в 21:10 ">15 August 2018 в 21:10 </span> </div> <a class="s-link" href="/questions/2365/otmechennoe-protiv-neizmenennogo-povedeniya-ob-ekta-v-funkciyax-python-duplicate#584" title="поделиться">поделиться</a> </div> <div class="post-layout--right"> <div id="comments-14104"> <ul class="comments-list js-comments-list" data-remaining-comments-count="0" data-canpost="false" data-cansee="true" data-comments-unavailable="false" data-addlink-disabled="true"> </ul> </div> </div> </div> </div> <div class="answer" id="14105" itemscope="" itemtype="http://schema.org/Answer"> <div class="answer-row"> <div class="answer-text"> <div class="description" itemprop="text"> <p> Это фактически не имеет ничего общего с значениями по умолчанию, кроме того, что часто возникает неожиданное поведение при записи функций с изменяемыми значениями по умолчанию. </p> <pre><code>>>> def foo(a): a.append(5) print a >>> a = [5] >>> foo(a) [5, 5] >>> foo(a) [5, 5, 5] >>> foo(a) [5, 5, 5, 5] >>> foo(a) [5, 5, 5, 5, 5] </code></pre> <p> В этом нет значений по умолчанию код, но вы получаете точно такую ​​же проблему. </p> <p> Проблема в том, что <code>foo</code> является <em> изменением </em> изменчивой переменной, переданной от вызывающего, когда вызывающий объект не ожидает этого , Код, подобный этому, был бы хорош, если бы функция была вызвана как-то вроде <code>append_5</code>; то вызывающий абонент будет вызывать функцию, чтобы изменить значение, которое они передают, и поведение будет ожидаться. Но такая функция вряд ли примет аргумент по умолчанию и, вероятно, не вернет список (поскольку у вызывающего уже есть ссылка на этот список, тот, который он только что передал). </p> <p> Ваш оригинал <code>foo</code> с аргументом по умолчанию не должен изменять <code>a</code>, был ли он явно передан или получил значение по умолчанию. Ваш код должен оставлять изменчивые аргументы отдельно, если из контекста / имени / документации не ясно, что аргументы должны быть изменены. Использование измененных значений, передаваемых в качестве аргументов, таких как локальные временные файлы, является крайне плохой идеей, независимо от того, находимся ли мы на Python или нет, и есть ли задействованные аргументы по умолчанию. </p> <p> Если вам нужно разрушить локальное временное в процессе вычисления чего-то, и вам нужно начать свою манипуляцию из значения аргумента, вам нужно сделать копию. </p> </div> <div class="votes-answer green"> <div class="vote-count" itemprop="upvoteCount">25</div><i class="fa fa-thumbs-o-up"></i> </div> <div class="clearfix"></div> <div class="action-time"> ответ дан Ben <span title="15 August 2018 в 21:10 ">15 August 2018 в 21:10 </span> </div> <a class="s-link" href="/questions/2365/otmechennoe-protiv-neizmenennogo-povedeniya-ob-ekta-v-funkciyax-python-duplicate#584" title="поделиться">поделиться</a> </div> <div class="post-layout--right"> <div id="comments-14105"> <ul class="comments-list js-comments-list" data-remaining-comments-count="0" data-canpost="false" data-cansee="true" data-comments-unavailable="false" data-addlink-disabled="true"> <li id="comment-22501" class="comment js-comment " data-comment-id="22501"> <div class="js-comment-actions comment-actions"> <div class="comment-score"> <span title="номер полезного комментария для вопроса" class="cool">1</span> </div> </div> <div class="comment-text js-comment-text-and-form"> <div style="display: block;" class="comment-body"> <span class="comment-copy">Хотя это связано, я думаю, что это отличное поведение (как мы ожидаем, <code>append</code> изменится <code>a</code> «на месте»). То, что измененный по умолчанию <b> не восстанавливается повторно при каждом вызове </b>, является «неожиданным». бит ... по крайней мере для меня. :) </span> – <span class="comment-user">Andy Hayden</span> <span class="comment-date" dir="ltr"><a class="comment-link" href="#comment14105_22501"><span title="24 August 2012 в 13:27 " class="relativetime-clean">24 August 2012 в 13:27 </span></a></span> </div> </div> </li> <li id="comment-22502" class="comment js-comment " data-comment-id="22502"> <div class="js-comment-actions comment-actions"> <div class="comment-score"> <span title="номер полезного комментария для вопроса" class="cool">2</span> </div> </div> <div class="comment-text js-comment-text-and-form"> <div style="display: block;" class="comment-body"> <span class="comment-copy">@AndyHayden, если функция <i> ожидается </ i>, чтобы изменить аргумент, почему имеет смысл иметь значение по умолчанию? </span> – <span class="comment-user">Mark Ransom</span> <span class="comment-date" dir="ltr"><a class="comment-link" href="#comment14105_22502"><span title="17 October 2017 в 13:31 " class="relativetime-clean">17 October 2017 в 13:31 </span></a></span> </div> </div> </li> <li id="comment-22503" class="comment js-comment " data-comment-id="22503"> <div class="js-comment-actions comment-actions"> <div class="comment-score"> <span title="номер полезного комментария для вопроса" class="cool">3</span> </div> </div> <div class="comment-text js-comment-text-and-form"> <div style="display: block;" class="comment-body"> <span class="comment-copy">@MarkRansom единственным примером, о котором я могу думать, является <code>cache={}</code>. Однако я подозреваю, что это «наименьшее удивление» появляется, когда вы <i> не </ i> ожидаете (или хотите) функцию, которую вы вызываете, для изменения аргумента. </span> – <span class="comment-user">Andy Hayden</span> <span class="comment-date" dir="ltr"><a class="comment-link" href="#comment14105_22503"><span title="17 October 2017 в 17:56 " class="relativetime-clean">17 October 2017 в 17:56 </span></a></span> </div> </div> </li> <li id="comment-22504" class="comment js-comment " data-comment-id="22504"> <div class="js-comment-actions comment-actions"> <div class="comment-score"> <span title="номер полезного комментария для вопроса" class="cool">4</span> </div> </div> <div class="comment-text js-comment-text-and-form"> <div style="display: block;" class="comment-body"> <span class="comment-copy">@AndyHayden Я оставил свой собственный ответ здесь с расширением этого чувства. Дайте мне знать, что вы думаете. Я мог бы добавить ваш пример <code>cache={}</code> в него для полноты. </span> – <span class="comment-user">Mark Ransom</span> <span class="comment-date" dir="ltr"><a class="comment-link" href="#comment14105_22504"><span title="17 October 2017 в 18:02 " class="relativetime-clean">17 October 2017 в 18:02 </span></a></span> </div> </div> </li> <li id="comment-22505" class="comment js-comment " data-comment-id="22505"> <div class="js-comment-actions comment-actions"> <div class="comment-score"> <span title="номер полезного комментария для вопроса" class="cool">5</span> </div> </div> <div class="comment-text js-comment-text-and-form"> <div style="display: block;" class="comment-body"> <span class="comment-copy">@AndyHayden Точка моего ответа заключается в том, что если вы когда-либо удивляетесь случайному изменению значения аргумента по умолчанию, то у вас есть еще одна ошибка, которая заключается в том, что ваш код может случайно изменить значение вызывающего абонента, когда значение по умолчанию <i> не было </ i>. И обратите внимание, что использование <code>None</code> и присвоение реального значения по умолчанию, если arg является <code>None</code> <i>, не разрешает эту проблему </ i> (я считаю, что это анти-шаблон по этой причине). Если вы исправите другую ошибку, избегая изменения значений аргументов независимо от того, имеют ли они значения по умолчанию, вы никогда не заметите или не позаботитесь об этом «удивительном». поведение. </span> – <span class="comment-user">Ben</span> <span class="comment-date" dir="ltr"><a class="comment-link" href="#comment14105_22505"><span title="17 October 2017 в 21:44 " class="relativetime-clean">17 October 2017 в 21:44 </span></a></span> </div> </div> </li> </ul> </div> </div> </div> </div> <div class="answer" id="14106" itemscope="" itemtype="http://schema.org/Answer"> <div class="answer-row"> <div class="answer-text"> <div class="description" itemprop="text"> <p> Я иногда использую это поведение как альтернативу следующему шаблону: </p> <pre><code>singleton = None def use_singleton(): global singleton if singleton is None: singleton = _make_singleton() return singleton.use_me() </code></pre> <p> Если <code>singleton</code> используется только <code>use_singleton</code>, мне нравится следующий шаблон в качестве замены: </p> <pre><code># _make_singleton() is called only once when the def is executed def use_singleton(singleton=_make_singleton()): return singleton.use_me() </code></pre> <p> Я использовал это для создания экземпляров клиентских классов, которые обращаются к внешним ресурсам, а также для создания dicts или списков для memoization. </p> <p> Поскольку я не думаю, что этот шаблон хорошо известен, Я поставил короткий комментарий для защиты от будущих недоразумений. </p> </div> <div class="votes-answer green"> <div class="vote-count" itemprop="upvoteCount">16</div><i class="fa fa-thumbs-o-up"></i> </div> <div class="clearfix"></div> <div class="action-time"> ответ дан bgreen-litl <span title="15 August 2018 в 21:10 ">15 August 2018 в 21:10 </span> </div> <a class="s-link" href="/questions/2365/otmechennoe-protiv-neizmenennogo-povedeniya-ob-ekta-v-funkciyax-python-duplicate#584" title="поделиться">поделиться</a> </div> <div class="post-layout--right"> <div id="comments-14106"> <ul class="comments-list js-comments-list" data-remaining-comments-count="0" data-canpost="false" data-cansee="true" data-comments-unavailable="false" data-addlink-disabled="true"> <li id="comment-22506" class="comment js-comment " data-comment-id="22506"> <div class="js-comment-actions comment-actions"> <div class="comment-score"> <span title="номер полезного комментария для вопроса" class="cool">1</span> </div> </div> <div class="comment-text js-comment-text-and-form"> <div style="display: block;" class="comment-body"> <span class="comment-copy">Я предпочитаю добавить декоратор для memoization и поместить кеш memoization на сам объект функции. </span> – <span class="comment-user">Stefano Borini</span> <span class="comment-date" dir="ltr"><a class="comment-link" href="#comment14106_22506"><span title="6 February 2015 в 08:34 " class="relativetime-clean">6 February 2015 в 08:34 </span></a></span> </div> </div> </li> <li id="comment-22507" class="comment js-comment " data-comment-id="22507"> <div class="js-comment-actions comment-actions"> <div class="comment-score"> <span title="номер полезного комментария для вопроса" class="cool">2</span> </div> </div> <div class="comment-text js-comment-text-and-form"> <div style="display: block;" class="comment-body"> <span class="comment-copy">Этот пример не заменяет более сложный шаблон, который вы показываете, потому что вы вызываете <code>_make_singleton</code> во время разбора в примере аргумента по умолчанию, но во время вызова в глобальном примере. Истинная подстановка будет использовать какой-то изменяемый поле для значения аргумента по умолчанию, но добавление аргумента дает возможность передавать альтернативные значения. </span> – <span class="comment-user">Yann Vernier</span> <span class="comment-date" dir="ltr"><a class="comment-link" href="#comment14106_22507"><span title="19 November 2017 в 09:29 " class="relativetime-clean">19 November 2017 в 09:29 </span></a></span> </div> </div> </li> </ul> </div> </div> </div> </div> <div class="answer" id="14107" itemscope="" itemtype="http://schema.org/Answer"> <div class="answer-row"> <div class="answer-text"> <div class="description" itemprop="text"> <p> Раньше я думал, что создание объектов во время выполнения будет лучшим подходом. Теперь я менее уверен, так как вы теряете некоторые полезные функции, хотя это может стоить того, что было бы просто для предотвращения путаницы новичков. Недостатками этого являются: </p> <p> 1. Производительность </p> <pre><code>def foo(arg=something_expensive_to_compute())): ... </code></pre> <p> Если используется оценка времени вызова, тогда дорогая функция вызывается каждый раз, когда ваша функция используется без аргумента. Вы либо заплатили бы дорогостоящую цену за каждый вызов, либо должны вручную кэшировать значение извне, загрязняя пространство имен и добавляя многословие. </p> <p> 2. Принудительные связанные параметры </p> <p> Полезный трюк заключается в привязке параметров лямбда к привязке <em> current </em> переменной при создании лямбда. Например: </p> <pre><code>funcs = [ lambda i=i: i for i in range(10)] </code></pre> <p> Возвращает список функций, возвращающих 0,1,2,3 ... соответственно. Если поведение изменено, они вместо этого привяжут <code>i</code> к значению <em> времени вызова </em> для i, поэтому вы получите список функций, которые все вернули <code>9</code>. </p> <p> Единственным способом реализации этого в противном случае было бы создать дальнейшее закрытие с привязкой i, то есть: </p> <pre><code>def make_func(i): return lambda: i funcs = [make_func(i) for i in range(10)] </code></pre> <p> 3. Introspection </p> <p> Рассмотрим код: </p> <pre><code>def foo(a='test', b=100, c=[]): print a,b,c </code></pre> <p> Мы можем получить информацию о аргументах и ​​значениях по умолчанию с помощью модуля <code>inspect</code>, который </p> <pre><code>>>> inspect.getargspec(foo) (['a', 'b', 'c'], None, None, ('test', 100, [])) </code></pre> <p> информация очень полезна для таких вещей, как создание документов, метапрограммирование, декораторы и т. д. </p> <p> Теперь предположим, что поведение по умолчанию может быть изменено так, что это эквивалентно: </p> <pre><code>_undefined = object() # sentinel value def foo(a=_undefined, b=_undefined, c=_undefined) if a is _undefined: a='test' if b is _undefined: b=100 if c is _undefined: c=[] </code></pre> <p> Однако мы потеряли способность интроспекции и посмотрим, какие аргументы по умолчанию <em> равны </em>. Поскольку объекты не были построены, мы никогда не сможем их захватить, не называя функцию. Самое лучшее, что мы могли бы сделать, это сохранить исходный код и вернуть его как строку. </p> </div> <div class="votes-answer green"> <div class="vote-count" itemprop="upvoteCount">50</div><i class="fa fa-thumbs-o-up"></i> </div> <div class="clearfix"></div> <div class="action-time"> ответ дан Brian <span title="15 August 2018 в 21:10 ">15 August 2018 в 21:10 </span> </div> <a class="s-link" href="/questions/2365/otmechennoe-protiv-neizmenennogo-povedeniya-ob-ekta-v-funkciyax-python-duplicate#584" title="поделиться">поделиться</a> </div> <div class="post-layout--right"> <div id="comments-14107"> <ul class="comments-list js-comments-list" data-remaining-comments-count="0" data-canpost="false" data-cansee="true" data-comments-unavailable="false" data-addlink-disabled="true"> <li id="comment-22508" class="comment js-comment " data-comment-id="22508"> <div class="js-comment-actions comment-actions"> <div class="comment-score"> <span title="номер полезного комментария для вопроса" class="cool">1</span> </div> </div> <div class="comment-text js-comment-text-and-form"> <div style="display: block;" class="comment-body"> <span class="comment-copy">вы могли бы достичь интроспекции также, если для каждой была функция для создания аргумента по умолчанию вместо значения. модуль проверки просто вызовет эту функцию. </span> – <span class="comment-user">yairchu</span> <span class="comment-date" dir="ltr"><a class="comment-link" href="#comment14107_22508"><span title="16 July 2009 в 11:24 " class="relativetime-clean">16 July 2009 в 11:24 </span></a></span> </div> </div> </li> <li id="comment-22509" class="comment js-comment " data-comment-id="22509"> <div class="js-comment-actions comment-actions"> <div class="comment-score"> <span title="номер полезного комментария для вопроса" class="cool">2</span> </div> </div> <div class="comment-text js-comment-text-and-form"> <div style="display: block;" class="comment-body"> <span class="comment-copy">@SilentGhost: Я говорю о том, было ли поведение изменено для его воссоздания - создание его однажды является текущим поведением и почему существует изменяемая проблема по умолчанию. </span> – <span class="comment-user">Brian</span> <span class="comment-date" dir="ltr"><a class="comment-link" href="#comment14107_22509"><span title="16 July 2009 в 11:59 " class="relativetime-clean">16 July 2009 в 11:59 </span></a></span> </div> </div> </li> <li id="comment-22510" class="comment js-comment " data-comment-id="22510"> <div class="js-comment-actions comment-actions"> <div class="comment-score"> <span title="номер полезного комментария для вопроса" class="cool">3</span> </div> </div> <div class="comment-text js-comment-text-and-form"> <div style="display: block;" class="comment-body"> <span class="comment-copy">@yairchu: Это предполагает, что конструкция безопасна для этого (т.е. не имеет побочных эффектов). Интроспекция args не должна <i> делать </ i> что-либо, но оценка произвольного кода вполне может привести к эффекту. </span> – <span class="comment-user">Brian</span> <span class="comment-date" dir="ltr"><a class="comment-link" href="#comment14107_22510"><span title="16 July 2009 в 12:02 " class="relativetime-clean">16 July 2009 в 12:02 </span></a></span> </div> </div> </li> <li id="comment-22511" class="comment js-comment " data-comment-id="22511"> <div class="js-comment-actions comment-actions"> <div class="comment-score"> <span title="номер полезного комментария для вопроса" class="cool">4</span> </div> </div> <div class="comment-text js-comment-text-and-form"> <div style="display: block;" class="comment-body"> <span class="comment-copy">Другой дизайн языка часто означает, что писать вещи по-разному. Ваш первый пример может быть легко написан как: _expensive = dear (); def foo (arg = _expensive), если вы специально <i> не </ i> хотите переоценить. </span> – <span class="comment-user">Glenn Maynard</span> <span class="comment-date" dir="ltr"><a class="comment-link" href="#comment14107_22511"><span title="16 July 2009 в 19:23 " class="relativetime-clean">16 July 2009 в 19:23 </span></a></span> </div> </div> </li> <li id="comment-22512" class="comment js-comment " data-comment-id="22512"> <div class="js-comment-actions comment-actions"> <div class="comment-score"> <span title="номер полезного комментария для вопроса" class="cool">5</span> </div> </div> <div class="comment-text js-comment-text-and-form"> <div style="display: block;" class="comment-body"> <span class="comment-copy">@Glenn - вот что я имел в виду с "кэшированием переменной извне" - он немного более подробный, но в конечном итоге вы получаете дополнительные переменные в своем пространстве имен. </span> – <span class="comment-user">Brian</span> <span class="comment-date" dir="ltr"><a class="comment-link" href="#comment14107_22512"><span title="16 July 2009 в 20:04 " class="relativetime-clean">16 July 2009 в 20:04 </span></a></span> </div> </div> </li> </ul> </div> </div> </div> </div> <div class="answer" id="14108" itemscope="" itemtype="http://schema.org/Answer"> <div class="answer-row"> <div class="answer-text"> <div class="description" itemprop="text"> <p> 1) Так называемая проблема «Mutable Default Argument» - это, в общем, специальный пример, демонстрирующий, что: «Все функции с этой проблемой также страдают от аналогичной проблемы побочного эффекта от фактического параметра». Это противоречит правилам <p> Пример: </p> <pre><code>def foo(a=[]): # the same problematic function a.append(5) return a >>> somevar = [1, 2] # an example without a default parameter >>> foo(somevar) [1, 2, 5] >>> somevar [1, 2, 5] # usually expected [1, 2] </code></pre> <p> Решение: копия Совершенно безопасным решением является <code>copy</code> или <code>deepcopy</code> входной сигнал сначала, а затем делать все с копией. </p> <pre><code>def foo(a=[]): a = a[:] # a copy a.append(5) return a # or everything safe by one line: "return a + [5]" </code></pre> <p> Многие встроенные изменяемые типы имеют метод копирования, такой как <code>some_dict.copy()</code> или <code>some_set.copy()</code>, или могут быть скопированы легко, как <code>somelist[:]</code> или <code>list(some_list)</code> , Каждый объект также может быть скопирован с помощью <code>copy.copy(any_object)</code> или более тщательным с помощью <code>copy.deepcopy()</code> (последний полезен, если изменяемый объект состоит из изменяемых объектов). Некоторые объекты основаны на побочных эффектах, таких как «файл», и не могут быть осмысленно воспроизведены копией. <a href="/go.php?url=http%3a%2f%2feffbot.org%2fpyfaq%2fhow-do-i-copy-an-object-in-python.htm" rel="noreferrer"> копирование </a> </p> <p> Пример проблемы для <a href="https://stackoverflow.com/q/13484107/448474"> аналогичного вопроса SO </a> </p> <pre><code>class Test(object): # the original problematic class def __init__(self, var1=[]): self._var1 = var1 somevar = [1, 2] # an example without a default parameter t1 = Test(somevar) t2 = Test(somevar) t1._var1.append([1]) print somevar # [1, 2, [1]] but usually expected [1, 2] print t2._var1 # [1, 2, [1]] but usually expected [1, 2] </code></pre> <p> Он не должен быть ни сохранен ни в одном <em> ] public </em> экземпляра, возвращаемого этой функцией. (Предполагая, что атрибуты <em> private </em> экземпляра не должны быть изменены извне этого класса или подкласса по соглашению, т. Е. <code>_var1</code> является частным атрибутом) </p> <p> Заключение: Параметры входных параметров shouldn 'изменяются на месте (мутированные), и они не должны быть привязаны к объекту, возвращаемому функцией. (Если мы предпочитаем программирование без побочных эффектов, которые настоятельно рекомендуются, см. <a href="/go.php?url=http%3a%2f%2fen.wikipedia.org%2fwiki%2fSide_effect_%2528computer_science%2529" rel="noreferrer"> Wiki о «побочном эффекте» </a> (первые два абзаца имеют смысл в этом контексте.).) </p> <p> 2) Только если побочный эффект на фактический параметр требуется, но нежелателен по параметру по умолчанию, тогда полезным решением является <code>def ...(var1=None):</code> <code>if var1 is None:</code> <code>var1 = []</code> <a href="/go.php?url=http%3a%2f%2feffbot.org%2fzone%2fdefault-values.htm%23what-to-do-instead" rel="noreferrer"> Подробнее .. </a> </p> <p> 3) В некоторых случаях <a href="/go.php?url=http%3a%2f%2feffbot.org%2fzone%2fdefault-values.htm%23valid-uses-for-mutable-defaults" rel="noreferrer"> используется изменчивое поведение параметров по умолчанию </a>. </p> </div> <div class="votes-answer green"> <div class="vote-count" itemprop="upvoteCount">29</div><i class="fa fa-thumbs-o-up"></i> </div> <div class="clearfix"></div> <div class="action-time"> ответ дан Community <span title="15 August 2018 в 21:10 ">15 August 2018 в 21:10 </span> </div> <a class="s-link" href="/questions/2365/otmechennoe-protiv-neizmenennogo-povedeniya-ob-ekta-v-funkciyax-python-duplicate#584" title="поделиться">поделиться</a> </div> <div class="post-layout--right"> <div id="comments-14108"> <ul class="comments-list js-comments-list" data-remaining-comments-count="0" data-canpost="false" data-cansee="true" data-comments-unavailable="false" data-addlink-disabled="true"> <li id="comment-22513" class="comment js-comment " data-comment-id="22513"> <div class="js-comment-actions comment-actions"> <div class="comment-score"> <span title="номер полезного комментария для вопроса" class="cool">1</span> </div> </div> <div class="comment-text js-comment-text-and-form"> <div style="display: block;" class="comment-body"> <span class="comment-copy">Надеюсь, вы знаете, что Python - это <i> not </ i> функциональный язык программирования. </span> – <span class="comment-user">Veky</span> <span class="comment-date" dir="ltr"><a class="comment-link" href="#comment14108_22513"><span title="8 May 2014 в 14:18 " class="relativetime-clean">8 May 2014 в 14:18 </span></a></span> </div> </div> </li> <li id="comment-22514" class="comment js-comment " data-comment-id="22514"> <div class="js-comment-actions comment-actions"> <div class="comment-score"> <span title="номер полезного комментария для вопроса" class="cool">2</span> </div> </div> <div class="comment-text js-comment-text-and-form"> <div style="display: block;" class="comment-body"> <span class="comment-copy">Да, Python - это язык с несколькими парамиггами с некоторыми функциональными возможностями. («Не делайте каждую проблему похожим на гвоздь только потому, что у вас есть молот».) Многие из них находятся в лучших практиках Python. Python имеет интересное функциональное программирование <a href="https://docs.python.org/2/howto/functional.html" rel="nofollow noreferrer"> HOWTO </a>. Другие функции - это закрытие и каррирование, не упомянутые здесь. </span> – <span class="comment-user">hynekcer</span> <span class="comment-date" dir="ltr"><a class="comment-link" href="#comment14108_22514"><span title="8 May 2014 в 16:54 " class="relativetime-clean">8 May 2014 в 16:54 </span></a></span> </div> </div> </li> <li id="comment-22515" class="comment js-comment " data-comment-id="22515"> <div class="js-comment-actions comment-actions"> <div class="comment-score"> <span title="номер полезного комментария для вопроса" class="cool">3</span> </div> </div> <div class="comment-text js-comment-text-and-form"> <div style="display: block;" class="comment-body"> <span class="comment-copy">На этом позднем этапе я также добавлю, что семантика назначения Python была разработана явно, чтобы избежать необходимости копирования данных там, где это необходимо, поэтому создание копий (и особенно глубоких копий) будет отрицательно сказаться на использовании времени выполнения и памяти. Поэтому их следует использовать только в случае необходимости, но новичкам часто бывает трудно понять, когда это происходит. </span> – <span class="comment-user">holdenweb</span> <span class="comment-date" dir="ltr"><a class="comment-link" href="#comment14108_22515"><span title="16 January 2018 в 15:27 " class="relativetime-clean">16 January 2018 в 15:27 </span></a></span> </div> </div> </li> <li id="comment-22516" class="comment js-comment " data-comment-id="22516"> <div class="js-comment-actions comment-actions"> <div class="comment-score"> <span title="номер полезного комментария для вопроса" class="cool">4</span> </div> </div> <div class="comment-text js-comment-text-and-form"> <div style="display: block;" class="comment-body"> <span class="comment-copy">@holdenweb Я согласен. Временная копия является наиболее обычным способом, а иногда и единственным возможным способом защиты исходных изменяемых данных от посторонней функции, которая их потенциально изменяет. К счастью, функция, которая необоснованно изменяет данные, считается ошибкой и поэтому необычна. </span> – <span class="comment-user">hynekcer</span> <span class="comment-date" dir="ltr"><a class="comment-link" href="#comment14108_22516"><span title="17 January 2018 в 22:41 " class="relativetime-clean">17 January 2018 в 22:41 </span></a></span> </div> </div> </li> <li id="comment-22517" class="comment js-comment " data-comment-id="22517"> <div class="js-comment-actions comment-actions"> <div class="comment-score"> <span title="номер полезного комментария для вопроса" class="cool">5</span> </div> </div> <div class="comment-text js-comment-text-and-form"> <div style="display: block;" class="comment-body"> <span class="comment-copy">Я согласен с этим ответом. И я не понимаю, почему конструкция <code>def f( a = None )</code> рекомендуется, когда вы действительно имеете в виду что-то еще. Копирование в порядке, потому что вы не должны мутировать аргументы. И когда вы делаете <code>if a is None: a = [1, 2, 3]</code>, вы все равно копируете список. </span> – <span class="comment-user">koddo</span> <span class="comment-date" dir="ltr"><a class="comment-link" href="#comment14108_22517"><span title="16 February 2018 в 17:15 " class="relativetime-clean">16 February 2018 в 17:15 </span></a></span> </div> </div> </li> </ul> </div> </div> </div> </div> <div class="answer" id="14109" itemscope="" itemtype="http://schema.org/Answer"> <div class="answer-row"> <div class="answer-text"> <div class="description" itemprop="text"> <p> Предположим, что у вас есть следующий код </p> <pre><code>fruits = ("apples", "bananas", "loganberries") def eat(food=fruits): ... </code></pre> <p> Когда я вижу декларацию о еде, наименее удивительной является мысль, что если первый параметр не указан, он будет равен tuple <code>("apples", "bananas", "loganberries")</code> </p> <p> Однако, предположим позже в коде, я делаю что-то вроде </p> <pre><code>def some_random_function(): global fruits fruits = ("blueberries", "mangos") </code></pre> <p>, тогда, если параметры по умолчанию были связаны с выполнением функции, а не с объявлением функции, тогда я бы удивляйтесь (очень плохо), чтобы обнаружить, что фрукты были изменены. Это было бы более удивительно ИМО, чем обнаружение того, что ваша функция <code>foo</code>, указанная выше, мутировала список. </p> <p> Реальная проблема заключается в изменяемых переменных, и все языки имеют определенную проблему. Возникает вопрос: предположим, что в Java у меня есть следующий код: </p> <pre class="lang-java prettyprint-override"><code>StringBuffer s = new StringBuffer("Hello World!"); Map<StringBuffer,Integer> counts = new HashMap<StringBuffer,Integer>(); counts.put(s, 5); s.append("!!!!"); System.out.println( counts.get(s) ); // does this work? </code></pre> <p> Теперь, использует ли моя карта значение ключа <code>StringBuffer</code>, когда оно было помещено на карту, или оно хранит ключ по ссылке? В любом случае, кто-то удивлен; либо человек, который попытался получить объект из <code>Map</code>, используя значение, идентичное тому, с которым он положил его, или человек, который, похоже, не может получить свой объект, даже если ключ, который они используют, буквально тот же объект, который использовался для размещения его на карте (на самом деле Python не позволяет использовать его изменяемые встроенные типы данных в качестве словарных клавиш). </p> <p> Ваш пример хороший случая, когда новички Python будут удивлены и укушены. Но я бы сказал, что если бы мы «исправили» это, тогда это создало бы другую ситуацию, в которой они были бы укушены, и это было бы еще менее интуитивным. Более того, это всегда имеет место при работе с изменяемыми переменными; вы всегда сталкиваетесь с ситуациями, когда кто-то может интуитивно ожидать одно или наоборот поведения в зависимости от того, какой код они пишут. </p> <p> Мне лично нравится текущий подход Python: аргументы функции по умолчанию оцениваются, когда функция определена, и что объект всегда является значением по умолчанию. Я предполагаю, что они могут использовать специальный случай с пустым списком, но такой специальный корпус вызовет еще большее удивление, не говоря уже о несовместимости в обратном направлении. </p> </div> <div class="votes-answer green"> <div class="vote-count" itemprop="upvoteCount">231</div><i class="fa fa-thumbs-o-up"></i> </div> <div class="clearfix"></div> <div class="action-time"> ответ дан das-g <span title="15 August 2018 в 21:10 ">15 August 2018 в 21:10 </span> </div> <a class="s-link" href="/questions/2365/otmechennoe-protiv-neizmenennogo-povedeniya-ob-ekta-v-funkciyax-python-duplicate#584" title="поделиться">поделиться</a> </div> <div class="post-layout--right"> <div id="comments-14109"> <ul class="comments-list js-comments-list" data-remaining-comments-count="0" data-canpost="false" data-cansee="true" data-comments-unavailable="false" data-addlink-disabled="true"> <li id="comment-22518" class="comment js-comment " data-comment-id="22518"> <div class="js-comment-actions comment-actions"> <div class="comment-score"> <span title="номер полезного комментария для вопроса" class="cool">1</span> </div> </div> <div class="comment-text js-comment-text-and-form"> <div style="display: block;" class="comment-body"> <span class="comment-copy">Я думаю, что это вопрос дебатов. Вы действуете на глобальной переменной. Любая оценка, выполняемая в любом месте вашего кода, включающего вашу глобальную переменную, теперь (правильно) относится к («черника», «манго»). параметр по умолчанию может быть похож на любой другой случай. </span> – <span class="comment-user">Stefano Borini</span> <span class="comment-date" dir="ltr"><a class="comment-link" href="#comment14109_22518"><span title="15 July 2009 в 19:16 " class="relativetime-clean">15 July 2009 в 19:16 </span></a></span> </div> </div> </li> <li id="comment-22519" class="comment js-comment " data-comment-id="22519"> <div class="js-comment-actions comment-actions"> <div class="comment-score"> <span title="номер полезного комментария для вопроса" class="cool">2</span> </div> </div> <div class="comment-text js-comment-text-and-form"> <div style="display: block;" class="comment-body"> <span class="comment-copy">На самом деле, я не думаю, что согласен с вашим первым примером. Я не уверен, что мне нравится идея изменить инициализатор, как это в первую очередь, но если бы я это сделал, я бы ожидал, что он будет вести себя точно так, как вы описали, - изменив значение по умолчанию на <code>("blueberries", "mangos")</code>. </span> – <span class="comment-user">Ben Blank</span> <span class="comment-date" dir="ltr"><a class="comment-link" href="#comment14109_22519"><span title="15 July 2009 в 19:26 " class="relativetime-clean">15 July 2009 в 19:26 </span></a></span> </div> </div> </li> <li id="comment-22520" class="comment js-comment " data-comment-id="22520"> <div class="js-comment-actions comment-actions"> <div class="comment-score"> <span title="номер полезного комментария для вопроса" class="cool">3</span> </div> </div> <div class="comment-text js-comment-text-and-form"> <div style="display: block;" class="comment-body"> <span class="comment-copy">Параметр по умолчанию <i> равен </ i>, как и любой другой случай. Неожиданным является то, что параметр является глобальной переменной, а не локальной. Это, в свою очередь, связано с тем, что код выполняется при определении функции, а не в вызове. Как только вы получите это, и что то же самое касается классов, это совершенно ясно. </span> – <span class="comment-user">Lennart Regebro</span> <span class="comment-date" dir="ltr"><a class="comment-link" href="#comment14109_22520"><span title="15 July 2009 в 19:59 " class="relativetime-clean">15 July 2009 в 19:59 </span></a></span> </div> </div> </li> <li id="comment-22521" class="comment js-comment " data-comment-id="22521"> <div class="js-comment-actions comment-actions"> <div class="comment-score"> <span title="номер полезного комментария для вопроса" class="cool">4</span> </div> </div> <div class="comment-text js-comment-text-and-form"> <div style="display: block;" class="comment-body"> <span class="comment-copy">Я нахожу пример вводящим в заблуждение, а не блестящим. Если <code>some_random_function()</code> присоединяется к <code>fruits</code> вместо назначения ему, поведение <code>eat()</code> <i> будет </ i> изменяться. Так много для настоящего замечательного дизайна. Если вы используете аргумент по умолчанию, который упоминается в другом месте, а затем изменить ссылку из-за пределов функции, вы просите о проблемах. Настоящий WTF - это когда люди определяют новый аргумент по умолчанию (литерал списка или вызов конструктора), а <i> still </ i> получают бит. </span> – <span class="comment-user">alexis</span> <span class="comment-date" dir="ltr"><a class="comment-link" href="#comment14109_22521"><span title="9 October 2014 в 16:37 " class="relativetime-clean">9 October 2014 в 16:37 </span></a></span> </div> </div> </li> <li id="comment-22522" class="comment js-comment " data-comment-id="22522"> <div class="js-comment-actions comment-actions"> <div class="comment-score"> <span title="номер полезного комментария для вопроса" class="cool">5</span> </div> </div> <div class="comment-text js-comment-text-and-form"> <div style="display: block;" class="comment-body"> <span class="comment-copy">Вы просто явно объявили <code>global</code> и переназначили кортеж - нет ничего удивительного, если <code>eat</code> работает по-другому после этого. </span> – <span class="comment-user">user3467349</span> <span class="comment-date" dir="ltr"><a class="comment-link" href="#comment14109_22522"><span title="26 January 2015 в 17:07 " class="relativetime-clean">26 January 2015 в 17:07 </span></a></span> </div> </div> </li> </ul> </div> </div> </div> </div> <div class="answer" id="14110" itemscope="" itemtype="http://schema.org/Answer"> <div class="answer-row"> <div class="answer-text"> <div class="description" itemprop="text"> <p> Такое поведение неудивительно, если принять во внимание следующее: </p> <ol> <li> Поведение атрибутов класса только для чтения при попытках назначения и что </li> <li> Функции являются объектами (хорошо объясняется в принятом ответе). </li> </ol> <p> Роль (2) была широко освещена в этой теме. (1), вероятно, является фактором, вызывающим удивление, поскольку это поведение не является «интуитивным» при поступлении с других языков. </p> <p> (1) описано в учебнике Python <a href="/go.php?url=http%3a%2f%2fdocs.python.org%2ftutorial%2fclasses.html"> по классам </a>. При попытке присвоить значение атрибуту класса только для чтения: </p> <blockquote> <p> ... все переменные, найденные вне самой внутренней области, доступны только для чтения (<em> попытка написать такую переменная просто создаст новую локальную переменную в самой внутренней области, оставив неизмененную идентичную внешнюю переменную неизменной </em>). </p> <p> Оглянитесь на исходный пример и рассмотрите приведенные выше пункты: </p> <pre><code>def foo(a=[]): a.append(5) return a </code></pre> <p> Здесь <code>foo</code> - объект, а <code>a</code> - атрибут <code>foo</code> (доступен в <code>foo.func_defs[0]</code>). Поскольку <code>a</code> является списком, <code>a</code> является изменяемым и, таким образом, является атрибутом чтения-записи <code>foo</code>. Он инициализируется пустым списком, указанным сигнатурой при создании экземпляра функции, и доступен для чтения и записи до тех пор, пока существует функциональный объект. </p> <p> Вызов <code>foo</code> без переопределения значения по умолчанию использует значение по умолчанию от <code>foo.func_defs</code>. В этом случае <code>foo.func_defs[0]</code> используется для <code>a</code> в пределах области кода объекта объекта. Изменения в <code>a</code> меняют <code>foo.func_defs[0]</code>, который является частью объекта <code>foo</code> и сохраняется между выполнением кода в <code>foo</code>. </p> <p> Теперь сравните это с примером из документации по <a href="/go.php?url=http%3a%2f%2fdocs.python.org%2ftutorial%2fcontrolflow.html%23default-argument-values">, эмулируя поведение аргументов по умолчанию других языков </a>, так что значения по умолчанию для функции используются каждый раз, когда функция выполняется: </p> <pre><code>def foo(a, L=None): if L is None: L = [] L.append(a) return L </code></pre> <p> Принимая во внимание (1) и (2) , можно понять, почему это выполняет желаемое поведение: </p> <ul> <li> Когда объект функции <code>foo</code> создается, <code>foo.func_defs[0]</code> установлен на <code>None</code>, неизменяемый объект. </li> <li> Когда функция выполняется с настройками по умолчанию (без функции, заданной для <code>L</code> в вызове функции), <code>foo.func_defs[0]</code> (<code>None</code>) доступен в локальной области как <code>L</code>. </li> <li> После <code>L = []</code> присваивание не может преуспеть в <code>foo.func_defs[0]</code>, поскольку этот атрибут доступен только для чтения. </li> <li> Per (1), <em> новая локальная переменная с именем <code>L</code> создается в локальной области </em> и используется для остальной части вызова функции. <code>foo.func_defs[0]</code>, таким образом, остается неизменным для будущих вызовов <code>foo</code>. </li> </ul> </blockquote> </div> <div class="votes-answer green"> <div class="vote-count" itemprop="upvoteCount">18</div><i class="fa fa-thumbs-o-up"></i> </div> <div class="clearfix"></div> <div class="action-time"> ответ дан Dmitry Minkovsky <span title="15 August 2018 в 21:10 ">15 August 2018 в 21:10 </span> </div> <a class="s-link" href="/questions/2365/otmechennoe-protiv-neizmenennogo-povedeniya-ob-ekta-v-funkciyax-python-duplicate#584" title="поделиться">поделиться</a> </div> <div class="post-layout--right"> <div id="comments-14110"> <ul class="comments-list js-comments-list" data-remaining-comments-count="0" data-canpost="false" data-cansee="true" data-comments-unavailable="false" data-addlink-disabled="true"> </ul> </div> </div> </div> </div> <div class="answer" id="14111" itemscope="" itemtype="http://schema.org/Answer"> <div class="answer-row"> <div class="answer-text"> <div class="description" itemprop="text"> <h1> Архитектура </h1> <p> Назначение значений по умолчанию в вызове функции - это запах кода. </p> <pre><code>def a(b=[]): pass </code></pre> <p> Это сигнатура функции, которая не подходит. Не только из-за проблем, описанных в других ответах. Я не буду вдаваться в это. </p> <p> Эта функция направлена ​​на то, чтобы сделать две вещи. Создайте новый список и выполните функциональность, скорее всего, в указанном списке. </p> <p> Функции, которые делают две вещи, являются плохими функциями, поскольку мы учимся на чистых практиках кода. </p> <p> Атака на эту проблему с полиморфизмом мы будем расширять список python или переносить его в класс, а затем выполнять свою функцию на нем. </p> <p> Но подождите, пока вы скажете, мне нравятся мои однострочные. </p> <p> Ну , Угадай, что. Код - это не просто способ управления поведением оборудования. Это способ: </p> <ul> <li> общаться с другими разработчиками, работающими над одним и тем же кодом. </li> <li> может изменить поведение аппаратного обеспечения при появлении новых требований. </li> <li>, способный понять поток программы после того, как вы снова забираете код через два года, чтобы сделать упомянутое выше изменение. </li> </ul> <p> Не оставляйте бомбы замедленного действия для себя <p> <p> Отделяя эту функцию от двух вещей, которые она делает, нам нужен класс </p> <pre><code>class ListNeedsFives(object): def __init__(self, b=None): if b is None: b = [] self.b = b def foo(): self.b.append(5) </code></pre> <p> Выполнено </p> <pre><code>a = ListNeedsFives() a.foo() a.b </code></pre> <p> И почему это лучше, чем слияние всего вышеописанного кода с одной функцией. </p> <pre><code>def dontdothis(b=None): if b is None: b = [] b.append(5) return b </code></pre> <p> Почему бы не сделать это? </p> <p> Если вы не сработаете в своем проекте, ваш код будет жить. Скорее всего, ваша функция будет делать больше, чем это. Правильный способ создания поддерживаемого кода состоит в том, чтобы разделить код на атомные части с должным образом ограниченным объемом. </p> <p> Конструктор класса является очень общепризнанным компонентом для всех, кто сделал объектно-ориентированное программирование. Размещение логики, которая обрабатывает экземпляр списка в конструкторе, делает когнитивную нагрузку понимания того, что делает код меньше. </p> <p> Метод <code>foo()</code> не возвращает список, почему бы и нет? </p> <p> При возврате отдельного списка вы можете предположить, что безопасно делать то, что вам хочется. Но это может быть не так, поскольку он также разделяется объектом <code>a</code>. Заставляя пользователя ссылаться на него как <code>a.b</code>, он напоминает, где находится список. Любой новый код, который хочет изменить <code>a.b</code>, естественно, будет помещен в класс, где он принадлежит. </p> <p> Функция подписи <code>def dontdothis(b=None):</code> не имеет ни одного из этих преимуществ. </p> </div> <div class="votes-answer"> <div class="vote-count" itemprop="upvoteCount">-2</div><i class="fa fa-thumbs-o-up"></i> </div> <div class="clearfix"></div> <div class="action-time"> ответ дан firelynx <span title="15 August 2018 в 21:10 ">15 August 2018 в 21:10 </span> </div> <a class="s-link" href="/questions/2365/otmechennoe-protiv-neizmenennogo-povedeniya-ob-ekta-v-funkciyax-python-duplicate#584" title="поделиться">поделиться</a> </div> <div class="post-layout--right"> <div id="comments-14111"> <ul class="comments-list js-comments-list" data-remaining-comments-count="0" data-canpost="false" data-cansee="true" data-comments-unavailable="false" data-addlink-disabled="true"> <li id="comment-22523" class="comment js-comment " data-comment-id="22523"> <div class="js-comment-actions comment-actions"> <div class="comment-score"> <span title="номер полезного комментария для вопроса" class="cool">1</span> </div> </div> <div class="comment-text js-comment-text-and-form"> <div style="display: block;" class="comment-body"> <span class="comment-copy">Я думаю, что ваш комментарий <i> & quot; Code - это больше, чем просто способ управления поведением аппаратного обеспечения & quot; </ i> - это отлично, но для того, чтобы сказать, что аргументы по умолчанию представляют собой запах кода, кажется слишком резким. Есть прекрасные причины для аргументов по умолчанию. </span> – <span class="comment-user">Bryan Oakley</span> <span class="comment-date" dir="ltr"><a class="comment-link" href="#comment14111_22523"><span title="14 November 2017 в 02:29 " class="relativetime-clean">14 November 2017 в 02:29 </span></a></span> </div> </div> </li> <li id="comment-22524" class="comment js-comment " data-comment-id="22524"> <div class="js-comment-actions comment-actions"> <div class="comment-score"> <span title="номер полезного комментария для вопроса" class="cool">2</span> </div> </div> <div class="comment-text js-comment-text-and-form"> <div style="display: block;" class="comment-body"> <span class="comment-copy">@BryanOakley Ну ... я честно написал этот ответ, когда я был в каком-то темном настроении ... понял, что, черт возьми, я могу просто выговорить о моем мнении. В любом случае вопрос довольно упрям ​​... Так ... да, спасибо за похвалу, я тоже принимаю вину близко к сердцу, хотя </span> – <span class="comment-user">firelynx</span> <span class="comment-date" dir="ltr"><a class="comment-link" href="#comment14111_22524"><span title="14 November 2017 в 20:05 " class="relativetime-clean">14 November 2017 в 20:05 </span></a></span> </div> </div> </li> </ul> </div> </div> </div> </div> <div class="answer" id="14112" itemscope="" itemtype="http://schema.org/Answer"> <div class="answer-row"> <div class="answer-text"> <div class="description" itemprop="text"> <p> Что вы спрашиваете, почему это: </p> <pre><code>def func(a=[], b = 2): pass </code></pre> <p> не является внутренне эквивалентным этому: </p> <pre><code>def func(a=None, b = None): a_default = lambda: [] b_default = lambda: 2 def actual_func(a=None, b=None): if a is None: a = a_default() if b is None: b = b_default() return actual_func func = func() </code></pre> <p>, за исключением случая прямого вызова func (None , None), которые мы будем игнорировать. </p> <p> Другими словами, вместо оценки параметров по умолчанию, почему бы не сохранить их каждый из них и оценить их при вызове функции? </p> <p> Один ответ, вероятно, прямо там - он фактически превратит каждую функцию с параметрами по умолчанию в закрытие. Даже если это все скрыто в интерпретаторе, а не полномасштабное закрытие, данные должны быть где-то сохранены. Он будет медленнее и будет использовать больше памяти. </p> </div> <div class="votes-answer green"> <div class="vote-count" itemprop="upvoteCount">30</div><i class="fa fa-thumbs-o-up"></i> </div> <div class="clearfix"></div> <div class="action-time"> ответ дан Glenn Maynard <span title="15 August 2018 в 21:10 ">15 August 2018 в 21:10 </span> </div> <a class="s-link" href="/questions/2365/otmechennoe-protiv-neizmenennogo-povedeniya-ob-ekta-v-funkciyax-python-duplicate#584" title="поделиться">поделиться</a> </div> <div class="post-layout--right"> <div id="comments-14112"> <ul class="comments-list js-comments-list" data-remaining-comments-count="0" data-canpost="false" data-cansee="true" data-comments-unavailable="false" data-addlink-disabled="true"> <li id="comment-22525" class="comment js-comment " data-comment-id="22525"> <div class="js-comment-actions comment-actions"> <div class="comment-score"> <span title="номер полезного комментария для вопроса" class="cool">1</span> </div> </div> <div class="comment-text js-comment-text-and-form"> <div style="display: block;" class="comment-body"> <span class="comment-copy">Это не было бы закрытием - лучший способ подумать об этом просто заставил бы байт-код создавать по умолчанию первую строку кода - ведь вы все равно компилируете тело в этой точке - нет никакой реальной разницы между кодом в аргументах и ​​коде в теле. </span> – <span class="comment-user">Brian</span> <span class="comment-date" dir="ltr"><a class="comment-link" href="#comment14112_22525"><span title="16 July 2009 в 10:39 " class="relativetime-clean">16 July 2009 в 10:39 </span></a></span> </div> </div> </li> <li id="comment-22526" class="comment js-comment " data-comment-id="22526"> <div class="js-comment-actions comment-actions"> <div class="comment-score"> <span title="номер полезного комментария для вопроса" class="cool">2</span> </div> </div> <div class="comment-text js-comment-text-and-form"> <div style="display: block;" class="comment-body"> <span class="comment-copy">Правда, но это все равно замедлит Python, и это будет действительно удивительно, если вы не сделаете то же самое для определений классов, что сделало бы его глупо медленным, так как вам пришлось бы повторно запускать все определение класса каждый раз, когда вы создаете экземпляр класс. Как уже упоминалось, исправление будет более удивительным, чем проблема. </span> – <span class="comment-user">Lennart Regebro</span> <span class="comment-date" dir="ltr"><a class="comment-link" href="#comment14112_22526"><span title="16 July 2009 в 12:49 " class="relativetime-clean">16 July 2009 в 12:49 </span></a></span> </div> </div> </li> <li id="comment-22527" class="comment js-comment " data-comment-id="22527"> <div class="js-comment-actions comment-actions"> <div class="comment-score"> <span title="номер полезного комментария для вопроса" class="cool">3</span> </div> </div> <div class="comment-text js-comment-text-and-form"> <div style="display: block;" class="comment-body"> <span class="comment-copy">Согласился с Леннартом. Поскольку Гвидо любит говорить, для каждой языковой функции или стандартной библиотеки есть <i> кто-то </ i>, используя ее. </span> – <span class="comment-user">Jason Baker</span> <span class="comment-date" dir="ltr"><a class="comment-link" href="#comment14112_22527"><span title="16 July 2009 в 14:21 " class="relativetime-clean">16 July 2009 в 14:21 </span></a></span> </div> </div> </li> <li id="comment-22528" class="comment js-comment " data-comment-id="22528"> <div class="js-comment-actions comment-actions"> <div class="comment-score"> <span title="номер полезного комментария для вопроса" class="cool">4</span> </div> </div> <div class="comment-text js-comment-text-and-form"> <div style="display: block;" class="comment-body"> <span class="comment-copy">Теперь изменить его было бы безумием - мы просто изучаем, почему так оно и есть. Если раньше начиналась оценка по умолчанию, это не обязательно было бы удивительно. Совершенно верно, что в таком ядре разница в синтаксическом анализе будет иметь широкий и, вероятно, много неясных последствий для языка в целом. </span> – <span class="comment-user">Glenn Maynard</span> <span class="comment-date" dir="ltr"><a class="comment-link" href="#comment14112_22528"><span title="16 July 2009 в 19:10 " class="relativetime-clean">16 July 2009 в 19:10 </span></a></span> </div> </div> </li> </ul> </div> </div> </div> </div> <div class="answer" id="14113" itemscope="" itemtype="http://schema.org/Answer"> <div class="answer-row"> <div class="answer-text"> <div class="description" itemprop="text"> <p> AFAICS никто еще не разместил соответствующую часть документации <a href="/go.php?url=http%3a%2f%2fdocs.python.org%2freference%2fcompound_stmts.html%23function-definitions"> </a>: </p> <blockquote> <p> Значения параметров по умолчанию оцениваются при выполнении определения функции. Это означает, что выражение оценивается один раз, когда функция определена, и что для каждого вызова используется одно и то же «предварительно вычисленное» значение. Это особенно важно для понимания, когда параметр по умолчанию является изменяемым объектом, таким как список или словарь: если функция изменяет объект (например, добавив элемент в список), значение по умолчанию изменяется. Обычно это не то, что было предназначено. Способ вокруг этого - использовать None как значение по умолчанию и явно проверить его в теле функции [...] </p> </blockquote> </div> <div class="votes-answer green"> <div class="vote-count" itemprop="upvoteCount">196</div><i class="fa fa-thumbs-o-up"></i> </div> <div class="clearfix"></div> <div class="action-time"> ответ дан glglgl <span title="15 August 2018 в 21:10 ">15 August 2018 в 21:10 </span> </div> <a class="s-link" href="/questions/2365/otmechennoe-protiv-neizmenennogo-povedeniya-ob-ekta-v-funkciyax-python-duplicate#584" title="поделиться">поделиться</a> </div> <div class="post-layout--right"> <div id="comments-14113"> <ul class="comments-list js-comments-list" data-remaining-comments-count="0" data-canpost="false" data-cansee="true" data-comments-unavailable="false" data-addlink-disabled="true"> <li id="comment-22529" class="comment js-comment " data-comment-id="22529"> <div class="js-comment-actions comment-actions"> <div class="comment-score"> <span title="номер полезного комментария для вопроса" class="cool">1</span> </div> </div> <div class="comment-text js-comment-text-and-form"> <div style="display: block;" class="comment-body"> <span class="comment-copy">Фразы «это обычно не то, что было предназначено». и "путь вокруг этого" запах, как будто они документируют недостаток дизайна. </span> – <span class="comment-user">bukzor</span> <span class="comment-date" dir="ltr"><a class="comment-link" href="#comment14113_22529"><span title="3 May 2014 в 21:53 " class="relativetime-clean">3 May 2014 в 21:53 </span></a></span> </div> </div> </li> <li id="comment-22530" class="comment js-comment " data-comment-id="22530"> <div class="js-comment-actions comment-actions"> <div class="comment-score"> <span title="номер полезного комментария для вопроса" class="cool">2</span> </div> </div> <div class="comment-text js-comment-text-and-form"> <div style="display: block;" class="comment-body"> <span class="comment-copy">@Matthew: Я хорошо знаю, но это не стоит ловушки. По этой причине вы, как правило, видите руководства по стилям и линтам, безусловно, ошибочно меняете изменчивые значения по умолчанию. Явный способ сделать то же самое - добавить атрибут в функцию (<code>function.data = []</code>) или еще лучше, создать объект. </span> – <span class="comment-user">bukzor</span> <span class="comment-date" dir="ltr"><a class="comment-link" href="#comment14113_22530"><span title="19 June 2014 в 04:59 " class="relativetime-clean">19 June 2014 в 04:59 </span></a></span> </div> </div> </li> <li id="comment-22531" class="comment js-comment " data-comment-id="22531"> <div class="js-comment-actions comment-actions"> <div class="comment-score"> <span title="номер полезного комментария для вопроса" class="cool">3</span> </div> </div> <div class="comment-text js-comment-text-and-form"> <div style="display: block;" class="comment-body"> <span class="comment-copy">@bukzor: Ловушки должны быть отмечены и задокументированы, поэтому этот вопрос хорош и получил так много upvotes. В то же время ловушки необязательно должны быть удалены. Сколько начинающих Python передали список функции, которая его модифицировала, и были потрясены, увидев, что изменения отображаются в исходной переменной? Однако изменчивые типы объектов замечательны, когда вы понимаете, как их использовать. Я думаю, это просто сводится к мнению об этой конкретной ловушке. </span> – <span class="comment-user">Matthew</span> <span class="comment-date" dir="ltr"><a class="comment-link" href="#comment14113_22531"><span title="19 June 2014 в 18:54 " class="relativetime-clean">19 June 2014 в 18:54 </span></a></span> </div> </div> </li> <li id="comment-22532" class="comment js-comment " data-comment-id="22532"> <div class="js-comment-actions comment-actions"> <div class="comment-score"> <span title="номер полезного комментария для вопроса" class="cool">4</span> </div> </div> <div class="comment-text js-comment-text-and-form"> <div style="display: block;" class="comment-body"> <span class="comment-copy">Фраза «это обычно не то, что было предназначено». означает "не то, что действительно хотел программист", & quot; не «не то, что должен делать Python». & quot; </span> – <span class="comment-user">holdenweb</span> <span class="comment-date" dir="ltr"><a class="comment-link" href="#comment14113_22532"><span title="19 December 2014 в 12:48 " class="relativetime-clean">19 December 2014 в 12:48 </span></a></span> </div> </div> </li> <li id="comment-22533" class="comment js-comment " data-comment-id="22533"> <div class="js-comment-actions comment-actions"> <div class="comment-score"> <span title="номер полезного комментария для вопроса" class="cool">5</span> </div> </div> <div class="comment-text js-comment-text-and-form"> <div style="display: block;" class="comment-body"> <span class="comment-copy">@oriadam Возможно, вы захотите задать вопрос об этом. Может быть, вы делаете что-то другое, чем предполагалось ... </span> – <span class="comment-user">glglgl</span> <span class="comment-date" dir="ltr"><a class="comment-link" href="#comment14113_22533"><span title="7 September 2015 в 07:28 " class="relativetime-clean">7 September 2015 в 07:28 </span></a></span> </div> </div> </li> </ul> </div> </div> </div> </div> <div class="answer" id="14114" itemscope="" itemtype="http://schema.org/Answer"> <div class="answer-row"> <div class="answer-text"> <div class="description" itemprop="text"> <p> Простейшее обходное решение, использующее None </p> <pre><code>>>> def bar(b, data=None): ... data = data or [] ... data.append(b) ... return data ... >>> bar(3) [3] >>> bar(3) [3] >>> bar(3) [3] >>> bar(3, [34]) [34, 3] >>> bar(3, [34]) [34, 3] </code></pre> </div> <div class="votes-answer green"> <div class="vote-count" itemprop="upvoteCount">18</div><i class="fa fa-thumbs-o-up"></i> </div> <div class="clearfix"></div> <div class="action-time"> ответ дан hugo24 <span title="15 August 2018 в 21:10 ">15 August 2018 в 21:10 </span> </div> <a class="s-link" href="/questions/2365/otmechennoe-protiv-neizmenennogo-povedeniya-ob-ekta-v-funkciyax-python-duplicate#584" title="поделиться">поделиться</a> </div> <div class="post-layout--right"> <div id="comments-14114"> <ul class="comments-list js-comments-list" data-remaining-comments-count="0" data-canpost="false" data-cansee="true" data-comments-unavailable="false" data-addlink-disabled="true"> </ul> </div> </div> </div> </div> <div class="answer" id="14115" itemscope="" itemtype="http://schema.org/Answer"> <div class="answer-row"> <div class="answer-text"> <div class="description" itemprop="text"> <p> Это оптимизация производительности. В результате этой функциональности, какой из этих двух вызовов функций вы считаете более быстрым? </p> <pre><code>def print_tuple(some_tuple=(1,2,3)): print some_tuple print_tuple() #1 print_tuple((1,2,3)) #2 </code></pre> <p> Я дам вам подсказку. Вот разборка (см. <a href="/go.php?url=http%3a%2f%2fdocs.python.org%2flibrary%2fdis.html" rel="noreferrer"> http://docs.python.org/library/dis.html </a>): </p> <h1> <code>#</code> 1 </h1> <pre><code>0 LOAD_GLOBAL 0 (print_tuple) 3 CALL_FUNCTION 0 6 POP_TOP 7 LOAD_CONST 0 (None) 10 RETURN_VALUE </code></pre> <h1> <code>#</code> 2 </h1> <pre><code> 0 LOAD_GLOBAL 0 (print_tuple) 3 LOAD_CONST 4 ((1, 2, 3)) 6 CALL_FUNCTION 1 9 POP_TOP 10 LOAD_CONST 0 (None) 13 RETURN_VALUE </code></pre> <blockquote> <p> Я сомневаюсь, что опытное поведение имеет практическое применение (кто действительно использовал статические переменные в C без размножающихся ошибок?) </p> <p> ] Как вы можете видеть, <em> - </em> преимущество производительности при использовании неизменяемых аргументов по умолчанию. Это может иметь значение, если это часто называемая функция или аргумент по умолчанию занимает много времени, чтобы построить. Кроме того, имейте в виду, что Python не C. В C у вас есть константы, которые в значительной степени свободны. В Python у вас нет этого преимущества. </p> </blockquote> </div> <div class="votes-answer green"> <div class="vote-count" itemprop="upvoteCount">24</div><i class="fa fa-thumbs-o-up"></i> </div> <div class="clearfix"></div> <div class="action-time"> ответ дан Jason Baker <span title="15 August 2018 в 21:10 ">15 August 2018 в 21:10 </span> </div> <a class="s-link" href="/questions/2365/otmechennoe-protiv-neizmenennogo-povedeniya-ob-ekta-v-funkciyax-python-duplicate#584" title="поделиться">поделиться</a> </div> <div class="post-layout--right"> <div id="comments-14115"> <ul class="comments-list js-comments-list" data-remaining-comments-count="0" data-canpost="false" data-cansee="true" data-comments-unavailable="false" data-addlink-disabled="true"> <li id="comment-22534" class="comment js-comment " data-comment-id="22534"> <div class="js-comment-actions comment-actions"> <div class="comment-score"> <span title="номер полезного комментария для вопроса" class="cool">1</span> </div> </div> <div class="comment-text js-comment-text-and-form"> <div style="display: block;" class="comment-body"> <span class="comment-copy">как вы получаете разборку? </span> – <span class="comment-user">Geo</span> <span class="comment-date" dir="ltr"><a class="comment-link" href="#comment14115_22534"><span title="16 July 2009 в 14:21 " class="relativetime-clean">16 July 2009 в 14:21 </span></a></span> </div> </div> </li> <li id="comment-22535" class="comment js-comment " data-comment-id="22535"> <div class="js-comment-actions comment-actions"> <div class="comment-score"> <span title="номер полезного комментария для вопроса" class="cool">2</span> </div> </div> <div class="comment-text js-comment-text-and-form"> <div style="display: block;" class="comment-body"> <span class="comment-copy">Используйте этот модуль: <a href="http://docs.python.org/library/dis.html" rel="nofollow noreferrer"> docs.python.org/library/dis.html </a> </span> – <span class="comment-user">Jason Baker</span> <span class="comment-date" dir="ltr"><a class="comment-link" href="#comment14115_22535"><span title="16 July 2009 в 16:20 " class="relativetime-clean">16 July 2009 в 16:20 </span></a></span> </div> </div> </li> <li id="comment-22536" class="comment js-comment " data-comment-id="22536"> <div class="js-comment-actions comment-actions"> <div class="comment-score"> <span title="номер полезного комментария для вопроса" class="cool">3</span> </div> </div> <div class="comment-text js-comment-text-and-form"> <div style="display: block;" class="comment-body"> <span class="comment-copy">Какая разница <code>3 LOAD_CONST 4 ((1, 2, 3))</code> может превысить миллионы итераций? ^ 0 ^. Может быть, я буду профилировать и отчитываться ... </span> – <span class="comment-user">Dmitry Minkovsky</span> <span class="comment-date" dir="ltr"><a class="comment-link" href="#comment14115_22536"><span title="31 March 2013 в 17:39 " class="relativetime-clean">31 March 2013 в 17:39 </span></a></span> </div> </div> </li> </ul> </div> </div> </div> </div> <div class="answer" id="14116" itemscope="" itemtype="http://schema.org/Answer"> <div class="answer-row"> <div class="answer-text"> <div class="description" itemprop="text"> <p> Вы можете обойти это, заменив объект (и, следовательно, связать область): </p> <pre><code>def foo(a=[]): a = list(a) a.append(5) return a </code></pre> <p> Ужасно, но он работает. </p> </div> <div class="votes-answer green"> <div class="vote-count" itemprop="upvoteCount">15</div><i class="fa fa-thumbs-o-up"></i> </div> <div class="clearfix"></div> <div class="action-time"> ответ дан jdborg <span title="15 August 2018 в 21:10 ">15 August 2018 в 21:10 </span> </div> <a class="s-link" href="/questions/2365/otmechennoe-protiv-neizmenennogo-povedeniya-ob-ekta-v-funkciyax-python-duplicate#584" title="поделиться">поделиться</a> </div> <div class="post-layout--right"> <div id="comments-14116"> <ul class="comments-list js-comments-list" data-remaining-comments-count="0" data-canpost="false" data-cansee="true" data-comments-unavailable="false" data-addlink-disabled="true"> <li id="comment-22537" class="comment js-comment " data-comment-id="22537"> <div class="js-comment-actions comment-actions"> <div class="comment-score"> <span title="номер полезного комментария для вопроса" class="cool">1</span> </div> </div> <div class="comment-text js-comment-text-and-form"> <div style="display: block;" class="comment-body"> <span class="comment-copy">Это хорошее решение в тех случаях, когда вы используете программное обеспечение для создания автоматической документации для документирования типов аргументов, ожидаемых функцией. Помещение a = None, а затем установка a на [], если a None, не помогает читателю понять с первого взгляда, что ожидается. </span> – <span class="comment-user">Michael Scott Cuthbert</span> <span class="comment-date" dir="ltr"><a class="comment-link" href="#comment14116_22537"><span title="20 January 2013 в 08:55 " class="relativetime-clean">20 January 2013 в 08:55 </span></a></span> </div> </div> </li> <li id="comment-22538" class="comment js-comment " data-comment-id="22538"> <div class="js-comment-actions comment-actions"> <div class="comment-score"> <span title="номер полезного комментария для вопроса" class="cool">2</span> </div> </div> <div class="comment-text js-comment-text-and-form"> <div style="display: block;" class="comment-body"> <span class="comment-copy">Лучше использовать docstring. </span> – <span class="comment-user">Aaron Hall♦</span> <span class="comment-date" dir="ltr"><a class="comment-link" href="#comment14116_22538"><span title="26 November 2014 в 00:23 " class="relativetime-clean">26 November 2014 в 00:23 </span></a></span> </div> </div> </li> <li id="comment-22539" class="comment js-comment " data-comment-id="22539"> <div class="js-comment-actions comment-actions"> <div class="comment-score"> <span title="номер полезного комментария для вопроса" class="cool">3</span> </div> </div> <div class="comment-text js-comment-text-and-form"> <div style="display: block;" class="comment-body"> <span class="comment-copy">Прохладная идея: повторное связывание этого имени гарантирует, что он никогда не будет изменен. Мне это очень нравится. </span> – <span class="comment-user">holdenweb</span> <span class="comment-date" dir="ltr"><a class="comment-link" href="#comment14116_22539"><span title="16 January 2018 в 15:29 " class="relativetime-clean">16 January 2018 в 15:29 </span></a></span> </div> </div> </li> <li id="comment-22540" class="comment js-comment " data-comment-id="22540"> <div class="js-comment-actions comment-actions"> <div class="comment-score"> <span title="номер полезного комментария для вопроса" class="cool">4</span> </div> </div> <div class="comment-text js-comment-text-and-form"> <div style="display: block;" class="comment-body"> <span class="comment-copy">Это именно то, как это сделать. Python не делает копию параметра, поэтому вам нужно сделать копию явно. После того, как у вас есть копия, она будет изменяться, как вам будет угодно, без каких-либо неожиданных побочных эффектов. </span> – <span class="comment-user">Mark Ransom</span> <span class="comment-date" dir="ltr"><a class="comment-link" href="#comment14116_22540"><span title="25 May 2018 в 16:56 " class="relativetime-clean">25 May 2018 в 16:56 </span></a></span> </div> </div> </li> </ul> </div> </div> </div> </div> <div class="answer" id="14117" itemscope="" itemtype="http://schema.org/Answer"> <div class="answer-row"> <div class="answer-text"> <div class="description" itemprop="text"> <p> Это легко объясняется: </p> <ol> <li> Объявление функции (класс и т. д.) выполняется только один раз, создавая все объекты значения по умолчанию </li> <li>, все передается по ссылке </li> </ol> <p> Итак: </p> <pre><code>def x(a=0, b=[], c=[], d=0): a = a + 1 b = b + [1] c.append(1) print a, b, c </code></pre> <ol> <li> <code>a</code> не изменяется - каждый вызов назначения создает новый объект int - печатается новый объект </li> <li> <code>b</code> не изменяется - новый массив создается из значения по умолчанию и печатается </li> <li> <code>c</code> изменения - операция выполняется на одном и том же объекте - и печатается </li> </ol> </div> <div class="votes-answer green"> <div class="vote-count" itemprop="upvoteCount">43</div><i class="fa fa-thumbs-o-up"></i> </div> <div class="clearfix"></div> <div class="action-time"> ответ дан Jim Fasarakis Hilliard <span title="15 August 2018 в 21:10 ">15 August 2018 в 21:10 </span> </div> <a class="s-link" href="/questions/2365/otmechennoe-protiv-neizmenennogo-povedeniya-ob-ekta-v-funkciyax-python-duplicate#584" title="поделиться">поделиться</a> </div> <div class="post-layout--right"> <div id="comments-14117"> <ul class="comments-list js-comments-list" data-remaining-comments-count="0" data-canpost="false" data-cansee="true" data-comments-unavailable="false" data-addlink-disabled="true"> <li id="comment-22541" class="comment js-comment " data-comment-id="22541"> <div class="js-comment-actions comment-actions"> <div class="comment-score"> <span title="номер полезного комментария для вопроса" class="cool">1</span> </div> </div> <div class="comment-text js-comment-text-and-form"> <div style="display: block;" class="comment-body"> <span class="comment-copy">Ваш №4 может сбивать с толку людей, поскольку целые числа являются неизменными и поэтому "if & quot; неправда. Например, с d, установленным в 0, d .__ add __ (1) вернет 1, но d все равно будет 0. </span> – <span class="comment-user">Anon</span> <span class="comment-date" dir="ltr"><a class="comment-link" href="#comment14117_22541"><span title="16 July 2009 в 00:45 " class="relativetime-clean">16 July 2009 в 00:45 </span></a></span> </div> </div> </li> <li id="comment-22542" class="comment js-comment " data-comment-id="22542"> <div class="js-comment-actions comment-actions"> <div class="comment-score"> <span title="номер полезного комментария для вопроса" class="cool">2</span> </div> </div> <div class="comment-text js-comment-text-and-form"> <div style="display: block;" class="comment-body"> <span class="comment-copy">(На самом деле, <b> add </b> - плохой пример, но целые числа неизменяемы по-прежнему являются моей основной точкой.) </span> – <span class="comment-user">Anon</span> <span class="comment-date" dir="ltr"><a class="comment-link" href="#comment14117_22542"><span title="16 July 2009 в 00:54 " class="relativetime-clean">16 July 2009 в 00:54 </span></a></span> </div> </div> </li> <li id="comment-22543" class="comment js-comment " data-comment-id="22543"> <div class="js-comment-actions comment-actions"> <div class="comment-score"> <span title="номер полезного комментария для вопроса" class="cool">3</span> </div> </div> <div class="comment-text js-comment-text-and-form"> <div style="display: block;" class="comment-body"> <span class="comment-copy">да, это не был хороший пример </span> – <span class="comment-user">ymv</span> <span class="comment-date" dir="ltr"><a class="comment-link" href="#comment14117_22543"><span title="16 July 2009 в 00:57 " class="relativetime-clean">16 July 2009 в 00:57 </span></a></span> </div> </div> </li> <li id="comment-22544" class="comment js-comment " data-comment-id="22544"> <div class="js-comment-actions comment-actions"> <div class="comment-score"> <span title="номер полезного комментария для вопроса" class="cool">4</span> </div> </div> <div class="comment-text js-comment-text-and-form"> <div style="display: block;" class="comment-body"> <span class="comment-copy">Понял это до моего огорчения после проверки, чтобы убедиться, что с b установлен в [], b .__ add __ ([1]) возвращает [1], но также оставляет b еще [], даже если списки изменяемы. Виноват. </span> – <span class="comment-user">Anon</span> <span class="comment-date" dir="ltr"><a class="comment-link" href="#comment14117_22544"><span title="16 July 2009 в 01:03 " class="relativetime-clean">16 July 2009 в 01:03 </span></a></span> </div> </div> </li> <li id="comment-22545" class="comment js-comment " data-comment-id="22545"> <div class="js-comment-actions comment-actions"> <div class="comment-score"> <span title="номер полезного комментария для вопроса" class="cool">5</span> </div> </div> <div class="comment-text js-comment-text-and-form"> <div style="display: block;" class="comment-body"> <span class="comment-copy">@ANon: есть <code>__iadd__</code>, но он не работает с int. Конечно. :-) </span> – <span class="comment-user">Veky</span> <span class="comment-date" dir="ltr"><a class="comment-link" href="#comment14117_22545"><span title="8 May 2014 в 14:16 " class="relativetime-clean">8 May 2014 в 14:16 </span></a></span> </div> </div> </li> <li id="comment-22546" class="comment js-comment " data-comment-id="22546"> <div class="js-comment-actions comment-actions"> <div class="comment-score"> <span title="номер полезного комментария для вопроса" class="cool">6</span> </div> </div> <div class="comment-text js-comment-text-and-form"> <div style="display: block;" class="comment-body"> <span class="comment-copy">Требуется ли <code>id(...)</code> для этой последней проверки или оператор <code>is</code> отвечает на тот же вопрос? </span> – <span class="comment-user">das-g</span> <span class="comment-date" dir="ltr"><a class="comment-link" href="#comment14117_22546"><span title="9 March 2016 в 09:09 " class="relativetime-clean">9 March 2016 в 09:09 </span></a></span> </div> </div> </li> <li id="comment-22547" class="comment js-comment " data-comment-id="22547"> <div class="js-comment-actions comment-actions"> <div class="comment-score"> <span title="номер полезного комментария для вопроса" class="cool">7</span> </div> </div> <div class="comment-text js-comment-text-and-form"> <div style="display: block;" class="comment-body"> <span class="comment-copy">@ das-g <code>is</code> будет отлично, я просто использовал <code>id(val)</code>, потому что думаю, что это может быть более интуитивно понятным. </span> – <span class="comment-user">Jim Fasarakis Hilliard</span> <span class="comment-date" dir="ltr"><a class="comment-link" href="#comment14117_22547"><span title="9 March 2016 в 09:20 " class="relativetime-clean">9 March 2016 в 09:20 </span></a></span> </div> </div> </li> <li id="comment-22548" class="comment js-comment " data-comment-id="22548"> <div class="js-comment-actions comment-actions"> <div class="comment-score"> <span title="номер полезного комментария для вопроса" class="cool">8</span> </div> </div> <div class="comment-text js-comment-text-and-form"> <div style="display: block;" class="comment-body"> <span class="comment-copy">@JimFasarakisHilliard Я бы добавил приглашение на <code>input</code>. как <code>input('Did you just see me without calling me?')</code>. Это делает его более понятным. </span> – <span class="comment-user">Ev. Kounis</span> <span class="comment-date" dir="ltr"><a class="comment-link" href="#comment14117_22548"><span title="1 September 2017 в 09:22 " class="relativetime-clean">1 September 2017 в 09:22 </span></a></span> </div> </div> </li> <li id="comment-22549" class="comment js-comment " data-comment-id="22549"> <div class="js-comment-actions comment-actions"> <div class="comment-score"> <span title="номер полезного комментария для вопроса" class="cool">9</span> </div> </div> <div class="comment-text js-comment-text-and-form"> <div style="display: block;" class="comment-body"> <span class="comment-copy">@ Ev.Kounis Мне это нравится! Спасибо что подметил это. </span> – <span class="comment-user">Jim Fasarakis Hilliard</span> <span class="comment-date" dir="ltr"><a class="comment-link" href="#comment14117_22549"><span title="1 September 2017 в 09:53 " class="relativetime-clean">1 September 2017 в 09:53 </span></a></span> </div> </div> </li> </ul> </div> </div> </div> </div> <div class="answer" id="14118" itemscope="" itemtype="http://schema.org/Answer"> <div class="answer-row"> <div class="answer-text"> <div class="description" itemprop="text"> <p> Это может быть правдой, что: </p> <ol> <li> Кто-то использует каждую функцию языка / библиотеки, а </li> <li>. Переключение поведения здесь было бы непродуманным, но </li> </ol> <p> полностью согласуется с обоими вышеперечисленными функциями и по-прежнему делает еще одну точку: </p> <ol start="3"> <li> Это запутанная функция, и это несчастливо в Python. </li> </ol> <p> Другие ответы или, по крайней мере, некоторые из них либо делают точки 1 и 2, но не 3, либо делают точки 3 и нижние точки 1 и 2. Но все три являются истинными. </p> <p> Возможно, что переключение лошадей в середине потока здесь потребует значительного поломки и что может возникнуть больше проблем, связанных с изменением Python, чтобы интуитивно обработать открывающий фрагмент Стефано. И это может быть правдой, что кто-то, кто хорошо знал внутренности Python, мог объяснить минные поля последствий. <em> Однако </em> </p> <p> Существующее поведение не является Pythonic, а Python успешным, потому что очень мало о языке нарушает принцип наименьшего удивления где-нибудь <em> возле </em>, это плохо , Это настоящая проблема, было бы разумно ее искоренить. Это дефект дизайна. Если вы понимаете язык намного лучше, пытаясь проследить поведение, я могу сказать, что C ++ делает все это и многое другое; вы многому научитесь, перейдя, например, на тонкие ошибки указателя. Но это не Pythonic: людям, которые заботятся о Python достаточно, чтобы упорствовать перед лицом этого поведения, являются люди, которые тянутся к этому языку, потому что у Python гораздо меньше сюрпризов, чем на другом языке. Dabblers и любопытные становятся Pythonistas, когда они удивляются тому, как мало времени требуется, чтобы получить что-то работающее - не из-за дизайна fl - я имею в виду, скрытая логическая головоломка - которая урезает интуицию программистов, которые тянутся к Python потому что он просто работает. </p> </div> <div class="votes-answer green"> <div class="vote-count" itemprop="upvoteCount">11</div><i class="fa fa-thumbs-o-up"></i> </div> <div class="clearfix"></div> <div class="action-time"> ответ дан JonathanHayward <span title="15 August 2018 в 21:10 ">15 August 2018 в 21:10 </span> </div> <a class="s-link" href="/questions/2365/otmechennoe-protiv-neizmenennogo-povedeniya-ob-ekta-v-funkciyax-python-duplicate#584" title="поделиться">поделиться</a> </div> <div class="post-layout--right"> <div id="comments-14118"> <ul class="comments-list js-comments-list" data-remaining-comments-count="0" data-canpost="false" data-cansee="true" data-comments-unavailable="false" data-addlink-disabled="true"> <li id="comment-22550" class="comment js-comment " data-comment-id="22550"> <div class="js-comment-actions comment-actions"> <div class="comment-score"> <span title="номер полезного комментария для вопроса" class="cool">1</span> </div> </div> <div class="comment-text js-comment-text-and-form"> <div style="display: block;" class="comment-body"> <span class="comment-copy">-1 Хотя оправданная перспектива, это не ответ, <b> и </b> я не согласен с этим. Слишком много особых исключений порождают собственные угловые случаи. </span> – <span class="comment-user">Marcin</span> <span class="comment-date" dir="ltr"><a class="comment-link" href="#comment14118_22550"><span title="7 July 2012 в 20:24 " class="relativetime-clean">7 July 2012 в 20:24 </span></a></span> </div> </div> </li> <li id="comment-22551" class="comment js-comment " data-comment-id="22551"> <div class="js-comment-actions comment-actions"> <div class="comment-score"> <span title="номер полезного комментария для вопроса" class="cool">2</span> </div> </div> <div class="comment-text js-comment-text-and-form"> <div style="display: block;" class="comment-body"> <span class="comment-copy">Таким образом, это «удивительно невежественное». сказать, что в Python было бы разумнее, если аргумент по умолчанию [] останется [] при каждом вызове функции? </span> – <span class="comment-user">JonathanHayward</span> <span class="comment-date" dir="ltr"><a class="comment-link" href="#comment14118_22551"><span title="28 December 2012 в 00:09 " class="relativetime-clean">28 December 2012 в 00:09 </span></a></span> </div> </div> </li> <li id="comment-22552" class="comment js-comment " data-comment-id="22552"> <div class="js-comment-actions comment-actions"> <div class="comment-score"> <span title="номер полезного комментария для вопроса" class="cool">3</span> </div> </div> <div class="comment-text js-comment-text-and-form"> <div style="display: block;" class="comment-body"> <span class="comment-copy">И невежественно рассматривать в качестве неудачной идиомы значение аргумента по умолчанию для None, а затем в теле тела функции, если аргумент == None: argument = []? Невероятно ли считать эту идиому неудачной, так как часто люди хотят того, чего ожидал наивный новичок, если вы назначили f (аргумент = []), аргумент автоматически по умолчанию будет иметь значение []? </span> – <span class="comment-user">JonathanHayward</span> <span class="comment-date" dir="ltr"><a class="comment-link" href="#comment14118_22552"><span title="28 December 2012 в 00:11 " class="relativetime-clean">28 December 2012 в 00:11 </span></a></span> </div> </div> </li> <li id="comment-22553" class="comment js-comment " data-comment-id="22553"> <div class="js-comment-actions comment-actions"> <div class="comment-score"> <span title="номер полезного комментария для вопроса" class="cool">4</span> </div> </div> <div class="comment-text js-comment-text-and-form"> <div style="display: block;" class="comment-body"> <span class="comment-copy">Но в Python часть духа языка состоит в том, что вам не нужно брать слишком много глубоких погружений; array.sort () работает и работает независимо от того, насколько мало вы понимаете сортировку, big-O и константы. Красота Python в механизме сортировки массивов, чтобы дать один из бесчисленных примеров, заключается в том, что вам не нужно глубоко погружаться во внутренние детали. И, говоря иначе, красота Python заключается в том, что обычно не требуется глубоко погружаться в реализацию, чтобы получить то, что Just Works. И есть обходное решение (... if argument == None: argument = []), FAIL. </span> – <span class="comment-user">JonathanHayward</span> <span class="comment-date" dir="ltr"><a class="comment-link" href="#comment14118_22553"><span title="28 December 2012 в 00:41 " class="relativetime-clean">28 December 2012 в 00:41 </span></a></span> </div> </div> </li> <li id="comment-22554" class="comment js-comment " data-comment-id="22554"> <div class="js-comment-actions comment-actions"> <div class="comment-score"> <span title="номер полезного комментария для вопроса" class="cool">5</span> </div> </div> <div class="comment-text js-comment-text-and-form"> <div style="display: block;" class="comment-body"> <span class="comment-copy">В качестве автономного оператора <code>x=[]</code> означает «создать пустой объект списка» и привязать к нему имя «x». & Quot; Таким образом, в <code>def f(x=[])</code> также создается пустой список. Он не всегда связан с x, поэтому вместо этого он привязывается к суррогату по умолчанию. Позже, когда вызывается f (), значение по умолчанию выгружается и привязывается к x. Поскольку это был пустой список, который был безвозвратно, тот же список - единственное, что доступно для привязки к x, независимо от того, что в нем было застряло или нет. Как же может быть иначе? </span> – <span class="comment-user">Jerry B</span> <span class="comment-date" dir="ltr"><a class="comment-link" href="#comment14118_22554"><span title="5 October 2013 в 07:18 " class="relativetime-clean">5 October 2013 в 07:18 </span></a></span> </div> </div> </li> </ul> </div> </div> </div> </div> <div class="answer" id="14119" itemscope="" itemtype="http://schema.org/Answer"> <div class="answer-row"> <div class="answer-text"> <div class="description" itemprop="text"> <p> Ну, причина в том, что привязки выполняются при выполнении кода, и выполняется определение функции, ну ... когда функции определены. </p> <p> Сравните это: </p> <pre><code>class BananaBunch: bananas = [] def addBanana(self, banana): self.bananas.append(banana) </code></pre> <p> Этот код страдает от такого же неожиданного случая. bananas - это атрибут класса, и, следовательно, когда вы добавляете к нему вещи, он добавляется ко всем экземплярам этого класса. Причина в том, что это точно то же самое. </p> <p> Это просто «Как это работает», и заставить его работать по-другому в функциональном случае, вероятно, будет сложно, а в случае класса вероятно невозможно или, по крайней мере, замедлить объект создание экземпляра, так как вам придется хранить код класса и выполнять его при создании объектов. </p> <p> Да, это неожиданно. Но как только пенни падает, она прекрасно вписывается в то, как работает Python в целом. На самом деле, это хорошее учебное пособие, и как только вы поймете, почему это происходит, вы будете намного лучше читать python. </p> <p> Это говорит о том, что он должен занимать видное место в любом хорошем учебнике Python. Потому что, как вы говорите, все рано или поздно сталкиваются с этой проблемой. </p> </div> <div class="votes-answer green"> <div class="vote-count" itemprop="upvoteCount">72</div><i class="fa fa-thumbs-o-up"></i> </div> <div class="clearfix"></div> <div class="action-time"> ответ дан Lennart Regebro <span title="15 August 2018 в 21:10 ">15 August 2018 в 21:10 </span> </div> <a class="s-link" href="/questions/2365/otmechennoe-protiv-neizmenennogo-povedeniya-ob-ekta-v-funkciyax-python-duplicate#584" title="поделиться">поделиться</a> </div> <div class="post-layout--right"> <div id="comments-14119"> <ul class="comments-list js-comments-list" data-remaining-comments-count="0" data-canpost="false" data-cansee="true" data-comments-unavailable="false" data-addlink-disabled="true"> <li id="comment-22555" class="comment js-comment " data-comment-id="22555"> <div class="js-comment-actions comment-actions"> <div class="comment-score"> <span title="номер полезного комментария для вопроса" class="cool">1</span> </div> </div> <div class="comment-text js-comment-text-and-form"> <div style="display: block;" class="comment-body"> <span class="comment-copy">Если для каждого экземпляра все иначе, это не атрибут класса. Атрибуты класса являются атрибутами CLASS. Отсюда и название. Следовательно, они одинаковы для всех случаев. </span> – <span class="comment-user">Lennart Regebro</span> <span class="comment-date" dir="ltr"><a class="comment-link" href="#comment14119_22555"><span title="15 July 2009 в 20:17 " class="relativetime-clean">15 July 2009 в 20:17 </span></a></span> </div> </div> </li> <li id="comment-22556" class="comment js-comment " data-comment-id="22556"> <div class="js-comment-actions comment-actions"> <div class="comment-score"> <span title="номер полезного комментария для вопроса" class="cool">2</span> </div> </div> <div class="comment-text js-comment-text-and-form"> <div style="display: block;" class="comment-body"> <span class="comment-copy">Он не просил описания поведения Питона, он просил объяснения. Ничто в Python не просто «Как это работает» ;; все это делает то, что делает по какой-то причине. </span> – <span class="comment-user">Glenn Maynard</span> <span class="comment-date" dir="ltr"><a class="comment-link" href="#comment14119_22556"><span title="15 July 2009 в 21:20 " class="relativetime-clean">15 July 2009 в 21:20 </span></a></span> </div> </div> </li> <li id="comment-22557" class="comment js-comment " data-comment-id="22557"> <div class="js-comment-actions comment-actions"> <div class="comment-score"> <span title="номер полезного комментария для вопроса" class="cool">3</span> </div> </div> <div class="comment-text js-comment-text-and-form"> <div style="display: block;" class="comment-body"> <span class="comment-copy">И я объяснил это. </span> – <span class="comment-user">Lennart Regebro</span> <span class="comment-date" dir="ltr"><a class="comment-link" href="#comment14119_22557"><span title="15 July 2009 в 22:56 " class="relativetime-clean">15 July 2009 в 22:56 </span></a></span> </div> </div> </li> <li id="comment-22558" class="comment js-comment " data-comment-id="22558"> <div class="js-comment-actions comment-actions"> <div class="comment-score"> <span title="номер полезного комментария для вопроса" class="cool">4</span> </div> </div> <div class="comment-text js-comment-text-and-form"> <div style="display: block;" class="comment-body"> <span class="comment-copy">Я бы не сказал, что это «хорошее учебное пособие», потому что это не так. </span> – <span class="comment-user">Geo</span> <span class="comment-date" dir="ltr"><a class="comment-link" href="#comment14119_22558"><span title="16 July 2009 в 14:20 " class="relativetime-clean">16 July 2009 в 14:20 </span></a></span> </div> </div> </li> <li id="comment-22559" class="comment js-comment " data-comment-id="22559"> <div class="js-comment-actions comment-actions"> <div class="comment-score"> <span title="номер полезного комментария для вопроса" class="cool">5</span> </div> </div> <div class="comment-text js-comment-text-and-form"> <div style="display: block;" class="comment-body"> <span class="comment-copy">@Geo: За исключением того, что это так. Это помогает вам понять многое на Python. </span> – <span class="comment-user">Lennart Regebro</span> <span class="comment-date" dir="ltr"><a class="comment-link" href="#comment14119_22559"><span title="16 July 2009 в 15:12 " class="relativetime-clean">16 July 2009 в 15:12 </span></a></span> </div> </div> </li> </ul> </div> </div> </div> </div> <div class="answer" id="14120" itemscope="" itemtype="http://schema.org/Answer"> <div class="answer-row"> <div class="answer-text"> <div class="description" itemprop="text"> <h1> 5 баллов в защиту Python </h1> <ol> <li> Простота: поведение прост в следующем смысле: большинство людей попадают в эту ловушку только один раз, а не несколько раз. </li> <li> Согласованность: Python <em> всегда </em> передает объекты, а не имена. Параметр по умолчанию, очевидно, является частью заголовка функции (а не тела функции). Поэтому он должен оцениваться при времени загрузки модуля (и только при времени загрузки модуля, если не вложен), а не во время вызова функции. </li> <li> Полезность: Как указывает Фредерик Лунд в своем объяснении <a href="/go.php?url=http%3a%2f%2feffbot.org%2fzone%2fdefault-values.htm%23valid-uses-for-mutable-defaults"> Значения параметров по умолчанию в Python "</a>, текущее поведение может быть весьма полезно для расширенного программирования. (Используйте экономно.) </li> <li> Достаточная документация: в самой базовой документации Python, в руководстве, проблема громко объявляется как «Важное предупреждение» в первом разделе <em> раздела </em> раздела <a href="/go.php?url=https%3a%2f%2fdocs.python.org%2f3%2ftutorial%2fcontrolflow.html%23default-argument-values"> «Подробнее о определении функций» </a>. Предупреждение даже использует жирный шрифт, который редко применяется за пределами заголовков. RTFM: прочитайте тонкое руководство. </li> <li> Мета-обучение: падение в ловушку на самом деле является очень полезным моментом (по крайней мере, если вы являетесь рефлексивным учеником), потому что впоследствии вы лучше поймете пункт «согласованность», выше, и это научит вас много о Python. </li> </ol> </div> <div class="votes-answer green"> <div class="vote-count" itemprop="upvoteCount">47</div><i class="fa fa-thumbs-o-up"></i> </div> <div class="clearfix"></div> <div class="action-time"> ответ дан Lutz Prechelt <span title="15 August 2018 в 21:10 ">15 August 2018 в 21:10 </span> </div> <a class="s-link" href="/questions/2365/otmechennoe-protiv-neizmenennogo-povedeniya-ob-ekta-v-funkciyax-python-duplicate#584" title="поделиться">поделиться</a> </div> <div class="post-layout--right"> <div id="comments-14120"> <ul class="comments-list js-comments-list" data-remaining-comments-count="0" data-canpost="false" data-cansee="true" data-comments-unavailable="false" data-addlink-disabled="true"> <li id="comment-22560" class="comment js-comment " data-comment-id="22560"> <div class="js-comment-actions comment-actions"> <div class="comment-score"> <span title="номер полезного комментария для вопроса" class="cool">1</span> </div> </div> <div class="comment-text js-comment-text-and-form"> <div style="display: block;" class="comment-body"> <span class="comment-copy">Мне потребовался год, чтобы найти, что такое поведение испортило мой код на производстве, в итоге удалило полную функцию, пока я случайно не столкнулся с этим недостатком дизайна. Я использую Django. Поскольку в промежуточной среде не было много запросов, эта ошибка никогда не оказывала влияния на качество. Когда мы поехали вживую и получили много одновременных запросов - некоторые служебные функции начали переписывать параметры друг друга! Делать дыры в безопасности, ошибки, а что нет. </span> – <span class="comment-user">oriadam</span> <span class="comment-date" dir="ltr"><a class="comment-link" href="#comment14120_22560"><span title="5 September 2015 в 13:09 " class="relativetime-clean">5 September 2015 в 13:09 </span></a></span> </div> </div> </li> <li id="comment-22561" class="comment js-comment " data-comment-id="22561"> <div class="js-comment-actions comment-actions"> <div class="comment-score"> <span title="номер полезного комментария для вопроса" class="cool">2</span> </div> </div> <div class="comment-text js-comment-text-and-form"> <div style="display: block;" class="comment-body"> <span class="comment-copy">@oriadam, не обижайтесь, но мне интересно, как вы научились Python, не сталкиваясь с этим раньше. Я просто изучаю Python сейчас, и эта возможная ловушка <a href="https://docs.python.org/3/tutorial/controlflow.html#default-argument-values" rel="nofollow noreferrer"> упоминается в официальном учебнике Python </a> рядом с первым упоминанием аргументов по умолчанию. (Как упоминалось в пункте 4 этого ответа.) Я полагаю, что мораль - скорее несимпатично - читать официальные документы <b> </b> языка, который вы используете для создания производственного программного обеспечения. </span> – <span class="comment-user">Wildcard</span> <span class="comment-date" dir="ltr"><a class="comment-link" href="#comment14120_22561"><span title="30 August 2016 в 02:26 " class="relativetime-clean">30 August 2016 в 02:26 </span></a></span> </div> </div> </li> <li id="comment-22562" class="comment js-comment " data-comment-id="22562"> <div class="js-comment-actions comment-actions"> <div class="comment-score"> <span title="номер полезного комментария для вопроса" class="cool">3</span> </div> </div> <div class="comment-text js-comment-text-and-form"> <div style="display: block;" class="comment-body"> <span class="comment-copy">Кроме того, было бы удивительно (для меня), если бы вызвала функцию неизвестной сложности в дополнение к вызову функции, которую я делаю. </span> – <span class="comment-user">Vatine</span> <span class="comment-date" dir="ltr"><a class="comment-link" href="#comment14120_22562"><span title="2 September 2016 в 13:26 " class="relativetime-clean">2 September 2016 в 13:26 </span></a></span> </div> </div> </li> </ul> </div> </div> </div> </div> <div class="answer" id="14121" itemscope="" itemtype="http://schema.org/Answer"> <div class="answer-row"> <div class="answer-text"> <div class="description" itemprop="text"> <p> Решения здесь: </p> <ol> <li> Используйте <code>None</code> в качестве значения по умолчанию (или nonce <code>object</code>) и включите его, чтобы создать свои значения во время выполнения; или </li> <li> Используйте параметр <code>lambda</code> в качестве параметра по умолчанию и вызовите его в блоке try, чтобы получить значение по умолчанию (это то, что требуется для лямбда-абстракции). </li> </ol> <p> Второй вариант хорош, потому что пользователи функции могут проходить в вызываемом, который может уже существовать (например, <code>type</code>) </p> </div> <div class="votes-answer green"> <div class="vote-count" itemprop="upvoteCount">17</div><i class="fa fa-thumbs-o-up"></i> </div> <div class="clearfix"></div> <div class="action-time"> ответ дан Marcin <span title="15 August 2018 в 21:10 ">15 August 2018 в 21:10 </span> </div> <a class="s-link" href="/questions/2365/otmechennoe-protiv-neizmenennogo-povedeniya-ob-ekta-v-funkciyax-python-duplicate#584" title="поделиться">поделиться</a> </div> <div class="post-layout--right"> <div id="comments-14121"> <ul class="comments-list js-comments-list" data-remaining-comments-count="0" data-canpost="false" data-cansee="true" data-comments-unavailable="false" data-addlink-disabled="true"> </ul> </div> </div> </div> </div> <div class="answer" id="14122" itemscope="" itemtype="http://schema.org/Answer"> <div class="answer-row"> <div class="answer-text"> <div class="description" itemprop="text"> <p> <em> Это не ошибка дизайна </em>. Любой, кто совершает это, делает что-то неправильно. </p> <p> Есть три случая, когда я вижу, где вы можете столкнуться с этой проблемой: </p> <ol> <li> Вы намерены изменить аргумент как сторону эффект функции. В этом случае <em> никогда не имеет смысла </em> иметь аргумент по умолчанию. Единственное исключение - когда вы злоупотребляете списком аргументов, чтобы иметь функциональные атрибуты, например. <code>cache={}</code>, и вы не должны были бы вызывать функцию с фактическим аргументом вообще. </li> <li> Вы намерены оставить аргумент немодифицированным, но вы случайно <em> сделали </em> изменить его , Это ошибка, исправьте ее. </li> <li> Вы намерены изменить аргумент для использования внутри функции, но не ожидали, что изменение будет доступно для просмотра вне функции. В этом случае вам нужно сделать <em> копию </em> аргумента, независимо от того, был ли он по умолчанию или нет! </li> </ol> <p> Пример в вопросе может относиться к категории 1 или 3. Нечетно, что он изменяет переданный список и возвращает его; вы должны выбрать тот или другой. </p> </div> <div class="votes-answer green"> <div class="vote-count" itemprop="upvoteCount">6</div><i class="fa fa-thumbs-o-up"></i> </div> <div class="clearfix"></div> <div class="action-time"> ответ дан Mark Ransom <span title="15 August 2018 в 21:10 ">15 August 2018 в 21:10 </span> </div> <a class="s-link" href="/questions/2365/otmechennoe-protiv-neizmenennogo-povedeniya-ob-ekta-v-funkciyax-python-duplicate#584" title="поделиться">поделиться</a> </div> <div class="post-layout--right"> <div id="comments-14122"> <ul class="comments-list js-comments-list" data-remaining-comments-count="0" data-canpost="false" data-cansee="true" data-comments-unavailable="false" data-addlink-disabled="true"> <li id="comment-22563" class="comment js-comment " data-comment-id="22563"> <div class="js-comment-actions comment-actions"> <div class="comment-score"> <span title="номер полезного комментария для вопроса" class="cool">1</span> </div> </div> <div class="comment-text js-comment-text-and-form"> <div style="display: block;" class="comment-body"> <span class="comment-copy">& quot; Делать что-то неправильно & quot; это диагноз. Тем не менее, я думаю, что времена были = Нет шаблон полезен, но обычно вы не хотите изменять, если в этом случае передается mutable (2). Шаблон <code>cache={}</code> - это действительно единственное решение для интервью, в реальном коде вы, вероятно, захотите <a href="https://docs.python.org/3/library/functools.html#functools.lru_cache" rel="nofollow noreferrer"> <code>@lru_cache</code> </a>! </span> – <span class="comment-user">Andy Hayden</span> <span class="comment-date" dir="ltr"><a class="comment-link" href="#comment14122_22563"><span title="17 October 2017 в 18:19 " class="relativetime-clean">17 October 2017 в 18:19 </span></a></span> </div> </div> </li> </ul> </div> </div> </div> </div> <div class="answer" id="14123" itemscope="" itemtype="http://schema.org/Answer"> <div class="answer-row"> <div class="answer-text"> <div class="description" itemprop="text"> <pre><code>>>> def a(): >>> print "a executed" >>> return [] >>> x =a() a executed >>> def b(m=[]): >>> m.append(5) >>> print m >>> b(x) [5] >>> b(x) [5, 5] </code></pre> </div> <div class="votes-answer green"> <div class="vote-count" itemprop="upvoteCount">5</div><i class="fa fa-thumbs-o-up"></i> </div> <div class="clearfix"></div> <div class="action-time"> ответ дан Martijn Pieters <span title="15 August 2018 в 21:10 ">15 August 2018 в 21:10 </span> </div> <a class="s-link" href="/questions/2365/otmechennoe-protiv-neizmenennogo-povedeniya-ob-ekta-v-funkciyax-python-duplicate#584" title="поделиться">поделиться</a> </div> <div class="post-layout--right"> <div id="comments-14123"> <ul class="comments-list js-comments-list" data-remaining-comments-count="0" data-canpost="false" data-cansee="true" data-comments-unavailable="false" data-addlink-disabled="true"> <li id="comment-22564" class="comment js-comment " data-comment-id="22564"> <div class="js-comment-actions comment-actions"> <div class="comment-score"> <span title="номер полезного комментария для вопроса" class="cool">1</span> </div> </div> <div class="comment-text js-comment-text-and-form"> <div style="display: block;" class="comment-body"> <span class="comment-copy">@AustinHenley отсутствие объяснения, что происходит? </span> – <span class="comment-user">Tshepang</span> <span class="comment-date" dir="ltr"><a class="comment-link" href="#comment14123_22564"><span title="24 February 2013 в 15:20 " class="relativetime-clean">24 February 2013 в 15:20 </span></a></span> </div> </div> </li> </ul> </div> </div> </div> </div> <div class="answer" id="14124" itemscope="" itemtype="http://schema.org/Answer"> <div class="answer-row"> <div class="answer-text"> <div class="description" itemprop="text"> <p> Эта «ошибка» дала мне много часов работы сверхурочных! Но я начинаю видеть его потенциальное использование (но мне хотелось бы, чтобы это было во время выполнения, все еще) </p> <p> Я дам вам то, что я вижу в качестве полезного примера. </p> <pre><code>def example(errors=[]): # statements # Something went wrong mistake = True if mistake: tryToFixIt(errors) # Didn't work.. let's try again tryToFixItAnotherway(errors) # This time it worked return errors def tryToFixIt(err): err.append('Attempt to fix it') def tryToFixItAnotherway(err): err.append('Attempt to fix it by another way') def main(): for item in range(2): errors = example() print '\n'.join(errors) main() </code></pre> <p> печатает следующие </p> <pre><code>Attempt to fix it Attempt to fix it by another way Attempt to fix it Attempt to fix it by another way </code></pre> </div> <div class="votes-answer green"> <div class="vote-count" itemprop="upvoteCount">9</div><i class="fa fa-thumbs-o-up"></i> </div> <div class="clearfix"></div> <div class="action-time"> ответ дан Norfeldt <span title="15 August 2018 в 21:10 ">15 August 2018 в 21:10 </span> </div> <a class="s-link" href="/questions/2365/otmechennoe-protiv-neizmenennogo-povedeniya-ob-ekta-v-funkciyax-python-duplicate#584" title="поделиться">поделиться</a> </div> <div class="post-layout--right"> <div id="comments-14124"> <ul class="comments-list js-comments-list" data-remaining-comments-count="0" data-canpost="false" data-cansee="true" data-comments-unavailable="false" data-addlink-disabled="true"> </ul> </div> </div> </div> </div> <div class="answer" id="14126" itemscope="" itemtype="http://schema.org/Answer"> <div class="answer-row"> <div class="answer-text"> <div class="description" itemprop="text"> <p> Когда мы это делаем: </p> <pre><code>def foo(a=[]): ... </code></pre> <p> ... мы присваиваем аргумент <code>a</code> списку <em> unnamed </em>, если вызывающий объект не передает значение a . </p> <p> Чтобы упростить эту дискуссию, давайте временно присвоим неназванному списку имя. Как насчет <code>pavlo</code>? </p> <pre><code>def foo(a=pavlo): ... </code></pre> <p> В любое время, если вызывающий абонент не сообщает нам, что <code>a</code>, мы повторно используем <code>pavlo</code>. </p> <p> Если <code>pavlo</code> изменен (модифицируется), а <code>foo</code> заканчивает его модификацию, эффект, который мы замечаем в следующий раз, <code>foo</code> вызывается без указания <code>a</code>. </p> <p> Итак, это то, что вы видите (помните, <code>pavlo</code> инициализируется в []): </p> <pre><code> >>> foo() [5] </code></pre> <p> Теперь <code>pavlo</code> - [5]. </p> <p> Вызов <code>foo()</code> снова снова изменяет <code>pavlo</code>: </p> <pre><code>>>> foo() [5, 5] </code></pre> <p> Задание <code>a</code> при вызове <code>foo()</code> гарантирует, что <code>pavlo</code> не коснулся. </p> <pre><code>>>> ivan = [1, 2, 3, 4] >>> foo(a=ivan) [1, 2, 3, 4, 5] >>> ivan [1, 2, 3, 4, 5] </code></pre> <p> Итак, <code>pavlo</code> все еще <code>[5, 5]</code>. </p> <pre><code>>>> foo() [5, 5, 5] </code></pre> </div> <div class="votes-answer green"> <div class="vote-count" itemprop="upvoteCount">14</div><i class="fa fa-thumbs-o-up"></i> </div> <div class="clearfix"></div> <div class="action-time"> ответ дан Saish <span title="15 August 2018 в 21:10 ">15 August 2018 в 21:10 </span> </div> <a class="s-link" href="/questions/2365/otmechennoe-protiv-neizmenennogo-povedeniya-ob-ekta-v-funkciyax-python-duplicate#584" title="поделиться">поделиться</a> </div> <div class="post-layout--right"> <div id="comments-14126"> <ul class="comments-list js-comments-list" data-remaining-comments-count="0" data-canpost="false" data-cansee="true" data-comments-unavailable="false" data-addlink-disabled="true"> </ul> </div> </div> </div> </div> <div class="answer" id="14127" itemscope="" itemtype="http://schema.org/Answer"> <div class="answer-row"> <div class="answer-text"> <div class="description" itemprop="text"> <p> Уже занятая тема, но из того, что я прочитал здесь, следующее помогло мне понять, как она работает внутри: </p> <pre><code>def bar(a=[]): print id(a) a = a + [1] print id(a) return a >>> bar() 4484370232 4484524224 [1] >>> bar() 4484370232 4484524152 [1] >>> bar() 4484370232 # Never change, this is 'class property' of the function 4484523720 # Always a new object [1] >>> id(bar.func_defaults[0]) 4484370232 </code></pre> </div> <div class="votes-answer green"> <div class="vote-count" itemprop="upvoteCount">22</div><i class="fa fa-thumbs-o-up"></i> </div> <div class="clearfix"></div> <div class="action-time"> ответ дан Stéphane <span title="15 August 2018 в 21:10 ">15 August 2018 в 21:10 </span> </div> <a class="s-link" href="/questions/2365/otmechennoe-protiv-neizmenennogo-povedeniya-ob-ekta-v-funkciyax-python-duplicate#584" title="поделиться">поделиться</a> </div> <div class="post-layout--right"> <div id="comments-14127"> <ul class="comments-list js-comments-list" data-remaining-comments-count="0" data-canpost="false" data-cansee="true" data-comments-unavailable="false" data-addlink-disabled="true"> <li id="comment-22570" class="comment js-comment " data-comment-id="22570"> <div class="js-comment-actions comment-actions"> <div class="comment-score"> <span title="номер полезного комментария для вопроса" class="cool">1</span> </div> </div> <div class="comment-text js-comment-text-and-form"> <div style="display: block;" class="comment-body"> <span class="comment-copy">на самом деле это может быть немного запутанным для новичков в качестве <code>a = a + [1]</code> перегрузок <code>a</code> ... рассмотреть возможность изменения его на <code>b = a + [1] ; print id(b)</code> и добавить строку <code>a.append(2)</code>. Это сделает более очевидным, что <code>+</code> в двух списках всегда создает новый список (назначается <code>b</code>), а модифицированный <code>a</code> может по-прежнему иметь тот же <code>id(a)</code>. </span> – <span class="comment-user">Jörn Hees</span> <span class="comment-date" dir="ltr"><a class="comment-link" href="#comment14127_22570"><span title="8 April 2017 в 13:47 " class="relativetime-clean">8 April 2017 в 13:47 </span></a></span> </div> </div> </li> </ul> </div> </div> </div> </div> <div class="answer" id="14128" itemscope="" itemtype="http://schema.org/Answer"> <div class="answer-row"> <div class="answer-text"> <div class="description" itemprop="text"> <p> Я думаю, что ответ на этот вопрос заключается в том, как python передает данные в параметр (передать по значению или по ссылке), а не изменчивость или как питон обрабатывает инструкцию «def». </p> <p> Краткое введение. Во-первых, в питоне есть два типа типов данных: один простой элементарный тип данных, например числа, а другой тип данных - объекты. Во-вторых, при передаче данных в параметры python передает элементарный тип данных по значению, т. Е. Делает локальную копию значения локальной переменной, но передает объект по ссылке, т. Е. Указывает на объект. </p> <p> Признавая вышеуказанные два момента, давайте объясним, что произошло с кодом python. Это происходит только из-за передачи по ссылке для объектов, но не имеет ничего общего с mutable / immutable или, возможно, факта, что оператор «def» выполняется только один раз, когда он определен. </p> <p> [] является объектом , поэтому python передает ссылку [] на <code>a</code>, т. е. <code>a</code> является только указателем на [], который лежит в памяти как объект. Существует только одна копия [] с, однако, многими ссылками на нее. Для первого foo () список [] изменен на <a href="/go.php?url=http%3a%2f%2feffbot.org%2fzone%2fdefault-values.htm" rel="noreferrer"> 1 </a> методом добавления. Но учтите, что существует только одна копия объекта списка, и этот объект теперь становится <a href="/go.php?url=http%3a%2f%2feffbot.org%2fzone%2fdefault-values.htm" rel="noreferrer"> 1 </a>. При запуске второго foo (), какая веб-страница effbot говорит (элементы больше не оцениваются) неверна. <code>a</code> оценивается как объект списка, хотя теперь содержимое объекта <a href="/go.php?url=http%3a%2f%2feffbot.org%2fzone%2fdefault-values.htm" rel="noreferrer"> 1 </a>. Это эффект прохождения по ссылке! Результат foo (3) может быть легко получен таким же образом. </p> <p> Чтобы еще раз подтвердить мой ответ, давайте рассмотрим два дополнительных кода. </p> <p> ===== = № 2 ======== </p> <pre><code>def foo(x, items=None): if items is None: items = [] items.append(x) return items foo(1) #return [1] foo(2) #return [2] foo(3) #return [3] </code></pre> <p> <code>[]</code> - это объект, поэтому <code>None</code> (первый является изменяемым, в то время как последний является неизменным, но изменчивость не имеет ничего что касается вопроса). Никто не находится где-то в пространстве, но мы знаем, что он есть, и там есть только одна копия «Нет». Таким образом, каждый раз, когда вызывается foo, элементы оцениваются (в отличие от некоторого ответа, который оценивается только один раз) равны None, чтобы быть ясным, ссылка (или адрес) None. Затем в foo элемент изменяется на [], т. Е. Указывает на другой объект, который имеет другой адрес. </p> <p> ====== № 3 ======= </p> <pre><code>def foo(x, items=[]): items.append(x) return items foo(1) # returns [1] foo(2,[]) # returns [2] foo(3) # returns [1,3] </code></pre> <p> Вызов элемента foo (1) указывает на объект списка [] с адрес, скажем, 11111111. содержимое списка будет изменено на <a href="/go.php?url=http%3a%2f%2feffbot.org%2fzone%2fdefault-values.htm" rel="noreferrer"> 1 </a> в функции foo в дальнейшем, но адрес не изменится, еще 11111111. Тогда foo (2, []) является приходит. Хотя [] в foo (2, []) имеет тот же контент, что и параметр по умолчанию [] при вызове foo (1), их адрес отличается! Поскольку мы предоставляем параметр явно, <code>items</code> должен принять адрес этого нового <code>[]</code>, скажем 2222222, и вернуть его после внесения некоторых изменений. Выполняется foo (3). поскольку предоставляется только <code>x</code>, элементы должны снова принимать значение по умолчанию. Что такое значение по умолчанию? Он задается при определении функции foo: объект списка, расположенный в 11111111. Таким образом, элементы оцениваются как адрес 11111111, имеющий элемент 1. Список, расположенный в 2222222, также содержит один элемент 2, но он не указывается элементами any Больше. Следовательно, добавление 3 сделает <code>items</code> [1,3]. </p> <p> Из приведенных выше объяснений видно, что веб-страница <a href="/go.php?url=http%3a%2f%2feffbot.org%2fzone%2fdefault-values.htm" rel="noreferrer"> effbot </a>, рекомендованная в принятом ответе, не дала соответствующего ответа на этот вопрос. Более того, я думаю, что точка на веб-странице effbot неверна. Я думаю, что код UI.Button верен: </p> <pre><code>for i in range(10): def callback(): print "clicked button", i UI.Button("button %s" % i, callback) </code></pre> <p> Каждая кнопка может содержать определенную функцию обратного вызова, которая будет отображать различное значение <code>i</code>. Я могу привести пример, чтобы показать это: </p> <pre><code>x=[] for i in range(10): def callback(): print(i) x.append(callback) </code></pre> <p> Если мы выполним <code>x[7]()</code>, мы получим 7, как ожидалось, и <code>x[9]()</code> даст 9, другое значение <code>i</code>. </p> </div> <div class="votes-answer green"> <div class="vote-count" itemprop="upvoteCount">8</div><i class="fa fa-thumbs-o-up"></i> </div> <div class="clearfix"></div> <div class="action-time"> ответ дан user2384994 <span title="15 August 2018 в 21:10 ">15 August 2018 в 21:10 </span> </div> <a class="s-link" href="/questions/2365/otmechennoe-protiv-neizmenennogo-povedeniya-ob-ekta-v-funkciyax-python-duplicate#584" title="поделиться">поделиться</a> </div> <div class="post-layout--right"> <div id="comments-14128"> <ul class="comments-list js-comments-list" data-remaining-comments-count="0" data-canpost="false" data-cansee="true" data-comments-unavailable="false" data-addlink-disabled="true"> <li id="comment-22571" class="comment js-comment " data-comment-id="22571"> <div class="js-comment-actions comment-actions"> <div class="comment-score"> <span title="номер полезного комментария для вопроса" class="cool">1</span> </div> </div> <div class="comment-text js-comment-text-and-form"> <div style="display: block;" class="comment-body"> <span class="comment-copy">Ваш последний пункт неверен. Попробуйте, и вы увидите, что <code>x[7]()</code> - <code>9</code>. </span> – <span class="comment-user">Duncan</span> <span class="comment-date" dir="ltr"><a class="comment-link" href="#comment14128_22571"><span title="2 October 2013 в 14:29 " class="relativetime-clean">2 October 2013 в 14:29 </span></a></span> </div> </div> </li> <li id="comment-22572" class="comment js-comment " data-comment-id="22572"> <div class="js-comment-actions comment-actions"> <div class="comment-score"> <span title="номер полезного комментария для вопроса" class="cool">2</span> </div> </div> <div class="comment-text js-comment-text-and-form"> <div style="display: block;" class="comment-body"> <span class="comment-copy">«элементарный тип данных прохода python по значению, т. е. делает локальную копию значения локальной переменной», совершенно неверно. Я удивлен, что кто-то может, очевидно, хорошо знать Python, но у него такое ужасное непонимание основ. :-( </span> – <span class="comment-user">Veky</span> <span class="comment-date" dir="ltr"><a class="comment-link" href="#comment14128_22572"><span title="19 November 2014 в 10:07 " class="relativetime-clean">19 November 2014 в 10:07 </span></a></span> </div> </div> </li> <li id="comment-22573" class="comment js-comment " data-comment-id="22573"> <div class="js-comment-actions comment-actions"> <div class="comment-score"> <span title="номер полезного комментария для вопроса" class="cool">3</span> </div> </div> <div class="comment-text js-comment-text-and-form"> <div style="display: block;" class="comment-body"> <span class="comment-copy">Был ли из-за тона, или вы думаете, что я говорю неправильно? </span> – <span class="comment-user">Veky</span> <span class="comment-date" dir="ltr"><a class="comment-link" href="#comment14128_22573"><span title="29 November 2014 в 06:38 " class="relativetime-clean">29 November 2014 в 06:38 </span></a></span> </div> </div> </li> </ul> </div> </div> </div> </div> <div class="answer" id="14129" itemscope="" itemtype="http://schema.org/Answer"> <div class="answer-row"> <div class="answer-text"> <div class="description" itemprop="text"> <p> Просто измените функцию: </p> <pre><code>def notastonishinganymore(a = []): '''The name is just a joke :)''' a = a[:] a.append(5) return a </code></pre> </div> <div class="votes-answer green"> <div class="vote-count" itemprop="upvoteCount">3</div><i class="fa fa-thumbs-o-up"></i> </div> <div class="clearfix"></div> <div class="action-time"> ответ дан ytpillai <span title="15 August 2018 в 21:10 ">15 August 2018 в 21:10 </span> </div> <a class="s-link" href="/questions/2365/otmechennoe-protiv-neizmenennogo-povedeniya-ob-ekta-v-funkciyax-python-duplicate#584" title="поделиться">поделиться</a> </div> <div class="post-layout--right"> <div id="comments-14129"> <ul class="comments-list js-comments-list" data-remaining-comments-count="0" data-canpost="false" data-cansee="true" data-comments-unavailable="false" data-addlink-disabled="true"> <li id="comment-22574" class="comment js-comment " data-comment-id="22574"> <div class="js-comment-actions comment-actions"> <div class="comment-score"> <span title="номер полезного комментария для вопроса" class="cool">1</span> </div> </div> <div class="comment-text js-comment-text-and-form"> <div style="display: block;" class="comment-body"> <span class="comment-copy">Это даже не законный Python. Почему 6 человек будут выдвигать этот ответ за пределы меня. </span> – <span class="comment-user">Aaron Hall♦</span> <span class="comment-date" dir="ltr"><a class="comment-link" href="#comment14129_22574"><span title="14 August 2016 в 00:14 " class="relativetime-clean">14 August 2016 в 00:14 </span></a></span> </div> </div> </li> <li id="comment-22575" class="comment js-comment " data-comment-id="22575"> <div class="js-comment-actions comment-actions"> <div class="comment-score"> <span title="номер полезного комментария для вопроса" class="cool">2</span> </div> </div> <div class="comment-text js-comment-text-and-form"> <div style="display: block;" class="comment-body"> <span class="comment-copy">Пожалуйста, определите, почему это не законный Python, если он работает, и мы не находимся в корпоративной ситуации с помощью своих правил </span> – <span class="comment-user">ytpillai</span> <span class="comment-date" dir="ltr"><a class="comment-link" href="#comment14129_22575"><span title="15 August 2016 в 14:21 " class="relativetime-clean">15 August 2016 в 14:21 </span></a></span> </div> </div> </li> <li id="comment-22576" class="comment js-comment " data-comment-id="22576"> <div class="js-comment-actions comment-actions"> <div class="comment-score"> <span title="номер полезного комментария для вопроса" class="cool">3</span> </div> </div> <div class="comment-text js-comment-text-and-form"> <div style="display: block;" class="comment-body"> <span class="comment-copy">Docstring помещалась в строку, определяющую функцию, поэтому есть синтаксическая ошибка. </span> – <span class="comment-user">Benjamin Engwall</span> <span class="comment-date" dir="ltr"><a class="comment-link" href="#comment14129_22576"><span title="7 August 2018 в 14:53 " class="relativetime-clean">7 August 2018 в 14:53 </span></a></span> </div> </div> </li> <li id="comment-214136" class="comment js-comment " data-comment-id="214136"> <div class="js-comment-actions comment-actions"> <div class="comment-score"> <span title="номер полезного комментария для вопроса" class="cool">4</span> </div> </div> <div class="comment-text js-comment-text-and-form"> <div style="display: block;" class="comment-body"> <span class="comment-copy"></span> – <span class="comment-user">Prune</span> <span class="comment-date" dir="ltr"><a class="comment-link" href="#comment14129_214136"><span title="6 September 2018 в 21:29 " class="relativetime-clean">6 September 2018 в 21:29 </span></a></span> </div> </div> </li> </ul> </div> </div> </div> </div> <div class="answer" id="97269" itemscope="" itemtype="http://schema.org/Answer"> <div class="answer-row"> <div class="answer-text"> <div class="description" itemprop="text"> </div> <div class="votes-answer green"> <div class="vote-count" itemprop="upvoteCount">45</div><i class="fa fa-thumbs-o-up"></i> </div> <div class="clearfix"></div> <div class="action-time"> ответ дан Jim Fasarakis Hilliard <span title="5 September 2018 в 20:41 ">5 September 2018 в 20:41 </span> </div> <a class="s-link" href="/questions/2365/otmechennoe-protiv-neizmenennogo-povedeniya-ob-ekta-v-funkciyax-python-duplicate#584" title="поделиться">поделиться</a> </div> <div class="post-layout--right"> <div id="comments-97269"> <ul class="comments-list js-comments-list" data-remaining-comments-count="0" data-canpost="false" data-cansee="true" data-comments-unavailable="false" data-addlink-disabled="true"> </ul> </div> </div> </div> </div> <div style="margin-top: 20px;"> Другие вопросы по тегам: <div class="tags" style="display: inline-block; float: none;"> <a href="/questions/tagged/python" class="tag" title="python" rel="tag">python</a> <a href="/questions/tagged/function" class="tag" title="function" rel="tag">function</a> <a href="/questions/tagged/immutability" class="tag" title="immutability" rel="tag">immutability</a> <a href="/questions/tagged/mutable" class="tag" title="mutable" rel="tag">mutable</a> </div> <h3 class="m-t-20">Похожие вопросы:</h3> <div class="related-block"> <ul> <li><div class='votes-answer green'><span class='vote-count'>123</span> <i class="fa fa-thumbs-o-up"></i></div> <a href="/questions/89525/skrytye-vozmozhnosti-python-zakryto" title="Скрытые возможности Python [закрыто]">Скрытые возможности Python [закрыто]</a> - 23 May 2017 12:34 </li> <li><div class='votes-answer green'><span class='vote-count'>78</span> <i class="fa fa-thumbs-o-up"></i></div> <a href="/questions/131651/luchshie-sposoby-uchit-novichka-k-programme-zakrytyj" title="Лучшие способы учить новичка к программе? [закрытый]">Лучшие способы учить новичка к программе? [закрытый]</a> - 24 November 2011 00:03 </li> <li><div class='votes-answer green'><span class='vote-count'>60</span> <i class="fa fa-thumbs-o-up"></i></div> <a href="/questions/82771/kak-razbit-spisok-na-kuski-odinakovogo-razmera" title="Как разбить список на куски одинакового размера?">Как разбить список на куски одинакового размера?</a> - 23 May 2017 11:55 </li> <li><div class='votes-answer green'><span class='vote-count'>50</span> <i class="fa fa-thumbs-o-up"></i></div> <a href="/questions/141660/kakovo-luchshee-nazvanie-nevidoizmenenija-dobavljaet-metod-na-neizmennom-nabore" title="Каково лучшее название невидоизменения, “добавляет” метод на неизменном наборе?">Каково лучшее название невидоизменения, “добавляет” метод на неизменном наборе?</a> - 27 January 2012 15:36 </li> <li><div class='votes-answer green'><span class='vote-count'>34</span> <i class="fa fa-thumbs-o-up"></i></div> <a href="/questions/131196/pochemu-izuchajut-perl-python-ruby-esli-kompanija-ispolzuet-c-c-ili-java-kak-jazyk-prilozhenija-zakrytyj" title="Почему изучают Perl, Python, Ruby, если компания использует C++, C# или Java как язык приложения? [закрытый]">Почему изучают Perl, Python, Ruby, если компания использует C++, C# или Java как язык приложения? [закрытый]</a> - 20 May 2010 08:15 </li> <li><div class='votes-answer green'><span class='vote-count'>33</span> <i class="fa fa-thumbs-o-up"></i></div> <a href="/questions/23418/vazhny-e-reversivny-e-pary-leetcode-time-out-duplicate" title="Важные реверсивные пары leetcode time out [duplicate] ">Важные реверсивные пары leetcode time out [duplicate] </a> - 25 October 2014 10:12 </li> <li><div class='votes-answer green'><span class='vote-count'>32</span> <i class="fa fa-thumbs-o-up"></i></div> <a href="/questions/16291/znacheniya-massiva-otobrazhaemy-e-v-sootvetstvii-s-usloviem-dublikat" title="Значения массива, отображаемые в соответствии с условием [дубликат] ">Значения массива, отображаемые в соответствии с условием [дубликат] </a> - 11 September 2013 01:02 </li> </ul> </div> </div> </div> </div> </div> <aside class="sidebar"> <div class="awrap"> <script async src="https://yastatic.net/pcode-native/loaders/loader.js"></script> <script> (yaads = window.yaads || []).push({ id: "553274-2", render: "#id-553274-2" }); </script> <div id="id-553274-2"></div> <script async src="//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script> <ins class="adsbygoogle" style="display:inline-block;width:300px;height:600px" data-ad-client="ca-pub-2355906945027976" data-ad-slot="8038370725"></ins> <script> (adsbygoogle = window.adsbygoogle || []).push({}); </script> </div> </aside> </div> </div> <footer class="footer"> <div class="wrapper wrapper--sm"> <div class="footer-navs-col"> <div class="footer-nav footer-nav--menu"> <div class="footer-coryright">© 2017 - 2020 Вопросы и ответы по программированию</div> </div> <div class="footer-nav footer-nav--catalog"> </div> </div> <div class="footer-contacts-col"> <div class="soc-widget-col"> </div> </div> <div class="clearfix"></div> </div> </footer> </div> <script type="text/javascript" src="/js/ui/jquery-ui-1.8.16.custom.min.js"></script> <script type="text/javascript" src="/js/ui/external/jquery.cookie.js"></script> <script type="text/javascript" src="/js/versions/menu.ru.u1607887878.js"></script> <script type="text/javascript" src="/js/jquery.fancybox.min.js"></script> <script type="text/javascript" src="/js/slick.min.js"></script> <script type="text/javascript" src="/js/jquery.maskedinput.min.js"></script> <script type="text/javascript" src="/js/versions/scripts.ru.u1607887878.js"></script> <!-- Yandex.Metrika counter --> <script type="text/javascript" > (function(m,e,t,r,i,k,a){m[i]=m[i]||function(){(m[i].a=m[i].a||[]).push(arguments)}; m[i].l=1*new Date();k=e.createElement(t),a=e.getElementsByTagName(t)[0],k.async=1,k.src=r,a.parentNode.insertBefore(k,a)}) (window, document, "script", "https://mc.yandex.ru/metrika/tag.js", "ym"); ym(61730716, "init", { clickmap:true, trackLinks:true, accurateTrackBounce:true }); </script> <noscript><div><img src="https://mc.yandex.ru/watch/61730716" style="position:absolute; left:-9999px;" alt="" /></div></noscript> <!-- /Yandex.Metrika counter --> <!-- Global site tag (gtag.js) - Google Analytics --> <script async src="https://www.googletagmanager.com/gtag/js?id=UA-123993370-1"></script> <script> window.dataLayer = window.dataLayer || []; function gtag(){dataLayer.push(arguments);} gtag('js', new Date()); gtag('config', 'UA-123993370-1'); </script> </div> <script type="application/ld+json"> { "@context": "https://schema.org", "@type": "WebSite", "name": "Программирование - вопросы и ответы", "alternateName": "Программирование - вопросы и ответы", "url": "https://legkovopros.ru", "potentialAction": { "@type": "SearchAction", "target": "https://legkovopros.ru/search?search={search_term_string}", "query-input": "required name=search_term_string" } } { "@context": "https://schema.org", "@type": "Organization", "name": "Программирование - вопросы и ответы", "url": "https://legkovopros.ru", "logo": "https://legkovopros.ru/i/logo.png", "email": "info@legkovopros.ru", "telephone": "" } </script> </body> </html>