Что pythonic путь состоит в том, чтобы избежать параметров по умолчанию, которые являются пустыми списками?

Ошибка анализа: синтаксическая ошибка, неожиданная '['

Эта ошибка возникает в двух вариантах:

Вариант 1

$arr = [1, 2, 3];

Синтаксис инициализатора этого массива был введен только в PHP 5.4; это приведет к возникновению ошибки парсера в версиях до этого. Если возможно, обновите свою установку или используйте старый синтаксис:

$arr = array(1, 2, 3);

См. Также этот пример из руководства.

Вариант 2

$suffix = explode(',', 'foo,bar')[1];

Результаты функции разыменования массива также были введены в PHP 5.4. Если обновление невозможно, вам нужно использовать временную переменную:

$parts = explode(',', 'foo,bar');
$suffix = $parts[1];

См. Также этот пример из руководства.

90
задан John Mulder 11 March 2019 в 20:04
поделиться

4 ответа

def my_func(working_list=None):
    if working_list is None: 
        working_list = []

    working_list.append("a")
    print(working_list)

в документах говорится, что необходимо использовать None в качестве значения по умолчанию и явно тест для него в теле функции.

124
ответ дан Boris 24 November 2019 в 07:04
поделиться

Не то, чтобы это имеет значение в этом случае, но можно использовать объектные идентификационные данные для тестирования ни на Один:

if working_list is None: working_list = []

Вы могли также использовать в своих интересах, как булев оператор или определяется в Python:

working_list = working_list or []

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

13
ответ дан bendin 24 November 2019 в 07:04
поделиться

Я мог бы быть вне темы, но помнить, что, если Вы просто хотите передать переменное количество аргументов, pythonic путь состоит в том, чтобы передать кортеж *args или словарь **kargs. Они являются дополнительными и являются лучше, чем синтаксис myFunc([1, 2, 3]).

, Если Вы хотите передать кортеж:

def myFunc(arg1, *args):
  print args
  w = []
  w += args
  print w
>>>myFunc(1, 2, 3, 4, 5, 6, 7)
(2, 3, 4, 5, 6, 7)
[2, 3, 4, 5, 6, 7]

, Если Вы хотите передать словарь:

def myFunc(arg1, **kargs):
   print kargs
>>>myFunc(1, option1=2, option2=3)
{'option2' : 2, 'option1' : 3}
3
ответ дан Mapad 24 November 2019 в 07:04
поделиться

Если функция предназначена для изменения параметра, переданного как working_list, смотрите ответ Генриха (=Нет, проверьте, нет ли внутри).

Но если вы не собирались мутировать аргумент, просто используйте его в качестве отправной точки для списка, вы можете просто скопировать его:

def myFunc(starting_list = []):
    starting_list = list(starting_list)
    starting_list.append("a")
    print starting_list

(или в этом простом случае просто распечатать start_list + ["a"], но я думаю, что это был просто игрушечный пример)

В общем, мутирование ваших аргументов - это плохой стиль на Python. Единственные функции, которые полностью ожидают мутации объекта - это методы объекта. Еще реже мутировать необязательный аргумент - разве побочный эффект, который случается только в некоторых вызовах, действительно лучший интерфейс?

  • Если вы делаете это из привычки C "выводить аргументы", то это совершенно ненужно - вы всегда можете вернуть несколько значений в качестве кортежа.

  • Если вы делаете это для того, чтобы эффективно строить длинный список результатов без построения промежуточных списков, то подумайте о том, чтобы написать его как генератор и использовать result_list.extension(myFunc()) при его вызове. Таким образом, ваши соглашения по вызову остаются очень чистыми.

Одним из паттернов, где часто происходит мутация необязательного аргумента is, является скрытый "memo" аргумент в рекурсивных функциях:

def depth_first_walk_graph(graph, node, _visited=None):
    if _visited is None:
        _visited = set()  # create memo once in top-level call

    if node in _visited:
        return
    _visited.add(node)
    for neighbour in graph[node]:
        depth_first_walk_graph(graph, neighbour, _visited)
10
ответ дан 24 November 2019 в 07:04
поделиться
Другие вопросы по тегам:

Похожие вопросы: