Избегать значения аргумента по умолчанию является изменяемым предупреждением (PyCharm) - PullRequest
0 голосов
/ 17 апреля 2020

Код:

def evaluate_fruit(fruits):
    for fruit in fruits:
        if fruit == "Apple":
            print("Good choice!")
        else:
            print("Meh its okay")


list_o_fruits = ["Apple", "Banana", "Orange"]

eval_list = (lambda x=list_o_fruits: evaluate_fruit(x))

eval_list()

Вывод:

Good choice!
Meh its okay
Meh its okay

Спасибо, что нашли время и прочитали это.

При запуске приведенного выше кода вывод будет таким, как ожидалось, однако PyCharm не нравится, когда я передаю список / словарь (изменяемый) в лямбда-функцию. Насколько я понимаю, это плохая практика объявлять список / словарь как значение функции по умолчанию, и это имеет смысл. Однако, что если я только прочту содержимое списка / словаря и не изменю его каким-либо образом внутри функции, будет ли это приемлемым тогда?

В любом случае, что будет лучшим подходом для объявления моей лямбда-функции с аргументом списка / словаря? В Интернете был предложен обходной путь для передачи изменяемой переменной по умолчанию в «нормальной» функции путем установки значения по умолчанию «Нет» с последующим использованием оператора if:

def evaluate_fruits(fruits=None):
    if fruits is None:
        fruits = []
    .
    .
    .

Я мог бы использовать эту концепцию для Лямбда-функция тоже, но тогда это сделало бы функцию неудобно длинной и избыточной, так как мне пришлось бы создавать условие if-оператора для каждой сгенерированной лямбды с помощью valu_fruits () (вроде бы побеждать цель использования лямбды). Примером может быть, если бы у меня было пять списков (list_o_fruits1, list_o_fruits2, ... list_o_fruits5), и я хотел создать лямбда-функцию для каждого из них (eval_list1, eval_list2, ... eval_list3) изvalu_fruits (). Могу я что-то пропустить?

1 Ответ

0 голосов
/ 17 апреля 2020

Если ваше единственное требование - объединить несколько элементов в один объект, и этот объект не должен быть изменяемым, используйте кортеж вместо списка. Кортежи обеспечивают одинаковое поведение списков, за исключением изменения их элементов. Точнее, изменяемые элементы все еще могут быть видоизменены, но элементы кортежа не могут быть назначены, добавлены или удалены, и сам кортеж считается неизменной структурой данных. Синтаксис для создания кортежа такой же, как и у списка, только с круглыми скобками вместо квадратных скобок:

# Immutable container with immutable elements, perfectly fine to use as a default argument
tuple_o_fruits = ("Apple", "Banana", "Orange")

Python Отсутствие универсальной c принудительной конст-корректности является одним из немногих вещи, которые действительно раздражают меня о языке. Стандартное решение - использовать встроенные неизменяемые типы данных, такие как tuple, вместо изменяемых, таких как list. Например, неизменной формой set является frozenset. Многие распространенные встроенные типы, такие как str, int и float, доступны только в неизменяемом виде. bytes - интересный случай, потому что неизменяемая форма более известна, чем ее изменяемая альтернатива bytearray. Самым выдающимся встроенным изменяемым типом, в котором отсутствует неизменная альтернатива, является dict (, но не сложно создать собственный ).

Итак, реальный ответ на вопрос «как избежать предупреждений?» об изменяемых аргументах по умолчанию ", 9 раз из 10, чтобы не использовать изменяемый объект, потому что неизменяемые альтернативы, как правило, легко доступны. Этого должно быть достаточно для вашего случая.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...