Решить проблему можно, передав в функцию что-то еще, чтобы указать на то, что вызов является первым:
>>> def nonbuggy(arg, result=None):
…·····if result is None:
…·········result = []
…·····result.append(arg)
…·····print(result)
…
>>> nonbuggy('a')
['a']
>>> nonbuggy('b')
['b']
Получаем позиционные аргументы с помощью *
Если вы работали с языками программирования C или C++, то можете предположить, что астериск (*) в Python как-то относится к указателям. Это не так, Python не имеет указателей.
Если символ * будет использован внутри функции с параметром, произвольное количество позиционных аргументов будет сгруппировано в кортеж. В следующем примере args является кортежем параметров, который был создан из аргументов, переданных в функцию print_args():
>>> def print_args(*args):
…·····print('Positional argument tuple:', args)
…
Если вы вызовете функцию без аргументов, то получите пустой кортеж:
>>> print_args()
Positional argument tuple: ()
Все аргументы, которые вы передадите, будут выведены на экран как кортеж args:
>>> print_args(3, 2, 1, 'wait!', 'uh…')
Positional argument tuple: (3, 2, 1, 'wait!', 'uh…')
Это полезно при написании функций вроде print(), которые принимают произвольное количество аргументов. Если в вашей функции имеются также обязательные позиционные аргументы, *args отправится в конец списка и получит все остальные аргументы:
>>> def print_more(required1, required2, *args):
…·····print('Need this one:', required1)
…·····print('Need this one too:', required2)
…·····print('All the rest:', args)
…
>>> print_more('cap', 'gloves', 'scarf', 'monocle', 'mustache wax')
Need this one: cap
Need this one too: gloves
All the rest: ('scarf', 'monocle', 'mustache wax')
При использовании * вам не нужно обязательно называть кортеж параметров args, однако это распространенная идиома в Python.
Получение аргументов — ключевых слов с помощью **
Вы можете использовать два астериска (**), чтобы сгруппировать аргументы — ключевые слова в словарь, где имена аргументов станут ключами, а их значения — соответствующими значениями в словаре. В следующем примере определяется функция print_kwargs(), в которой выводятся ее аргументы — ключевые слова:
>>> def print_kwargs(**kwargs):
…·····print('Keyword arguments:', kwargs)
…
Теперь попробуйте вызвать ее, передав несколько аргументов:
>>> print_kwargs(wine='merlot', entree='mutton', dessert='macaroon')
Keyword arguments: {'dessert': 'macaroon', 'wine': 'merlot', 'entree': 'mutton'}
Внутри функции kwargs является словарем.
Если вы используете позиционные аргументы и аргументы — ключевые слова (*args и **kwargs), они должны следовать в этом же порядке. Как и в случае с args, вам не обязательно называть этот словарь kwargs, но это опять же является распространенной практикой.
Строки документации
Дзен Python гласит: удобочитаемость имеет значение. Вы можете прикрепить документацию к определению функции, включив строку в начало ее тела. Она называется строкой документации:
>>> def echo(anything):
…·····'echo returns its input argument'
…·····return anything
Вы можете сделать строку документации довольно длинной и даже, если хотите, применить к ней форматирование, что показано в следующем примере:
def print_if_true(thing, check):
····'''
····Prints the first argument if a second argument is true.
····The operation is:
········1. Check whether the *second* argument is true.
········2. If it is, print the *first* argument.
····'''
····if check:
········print(thing)