Почему вы используете None в качестве Sentinel в функции в Python? - PullRequest
1 голос
/ 29 марта 2020

версия 1

def add_author(authors_books, current_books=None):
  if current_books is None:
    current_books = []

  current_books.extend(authors_books)
  return current_books

версия 2

def add_author(authors_books):
  current_books = []
  current_books.extend(authors_books)
  return current_books

В версии 1 зачем вам использовать "current_books = None" и следующий оператор "if", если вы можете получить то же самое результат использования функции в версии 2?

Есть ли определенные случаи использования, в которых вы бы поставили параметр как = None?

1 Ответ

1 голос
/ 29 марта 2020

Например, при написании рекурсивной функции, которая должна передавать что-то изменяемое, например, список. Пример игрушки:

def foo(collected=None, level=0, max_depth=3):
    if collected is None: # first call!
        collected = []

    collected.append(level)    
    print(collected)

    if level < max_depth:
        foo(collected, level + 1, max_depth)

foo()

# output:
# [0]
# [0, 1]
# [0, 1, 2]
# [0, 1, 2, 3]

Аргумент по умолчанию для collected используется так, что первому вызывающему абоненту не нужно указывать collected=[].

None используется вместо [] в качестве значения по умолчанию, так что мутации в collected не сохраняются во время вызовов (изменяемый аргумент Python по умолчанию) -

def foo(collected=[], level=0, max_depth=3):
    collected.append(level)    
    print(collected)

    if level < max_depth:
        foo(collected, level + 1, max_depth)

foo()

# output:
# [0]
# [0, 1]
# [0, 1, 2]
# [0, 1, 2, 3]

foo()

# output:    
# [0, 1, 2, 3, 0]
# [0, 1, 2, 3, 0, 1]
# [0, 1, 2, 3, 0, 1, 2]
# [0, 1, 2, 3, 0, 1, 2, 3]
...