Назначение значений по умолчанию в вызове функции - это запах кода.
def a(b=[]):
pass
Это сигнатура функции, которая не подходит. Не только из-за проблем, описанных в других ответах. Я не буду вдаваться в это.
Эта функция направлена на то, чтобы сделать две вещи. Создайте новый список и выполните функциональность, скорее всего, в указанном списке.
Функции, которые делают две вещи, являются плохими функциями, поскольку мы учимся на чистых практиках кода.
Атака на эту проблему с полиморфизмом мы будем расширять список python или переносить его в класс, а затем выполнять свою функцию на нем.
Но подождите, пока вы скажете, мне нравятся мои однострочные.
Ну , Угадай, что. Код - это не просто способ управления поведением оборудования. Это способ:
Не оставляйте бомбы замедленного действия для себя
Отделяя эту функцию от двух вещей, которые она делает, нам нужен класс
class ListNeedsFives(object):
def __init__(self, b=None):
if b is None:
b = []
self.b = b
def foo():
self.b.append(5)
Выполнено
a = ListNeedsFives()
a.foo()
a.b
И почему это лучше, чем слияние всего вышеописанного кода с одной функцией.
def dontdothis(b=None):
if b is None:
b = []
b.append(5)
return b
Почему бы не сделать это?
Если вы не сработаете в своем проекте, ваш код будет жить. Скорее всего, ваша функция будет делать больше, чем это. Правильный способ создания поддерживаемого кода состоит в том, чтобы разделить код на атомные части с должным образом ограниченным объемом.
Конструктор класса является очень общепризнанным компонентом для всех, кто сделал объектно-ориентированное программирование. Размещение логики, которая обрабатывает экземпляр списка в конструкторе, делает когнитивную нагрузку понимания того, что делает код меньше.
Метод foo()
не возвращает список, почему бы и нет?
При возврате отдельного списка вы можете предположить, что безопасно делать то, что вам хочется. Но это может быть не так, поскольку он также разделяется объектом a
. Заставляя пользователя ссылаться на него как a.b
, он напоминает, где находится список. Любой новый код, который хочет изменить a.b
, естественно, будет помещен в класс, где он принадлежит.
Функция подписи def dontdothis(b=None):
не имеет ни одного из этих преимуществ.