- en
- Language: ru
- Documentation version: latest
Создание функций
Создание функции:
функции создаются с помощью зарезервированного слова def
за def следуют имя функции и круглые скобки
внутри скобок могут указываться параметры, которые функция принимает
после круглых скобок идет двоеточие и с новой строки, с отступом, идет блок кода, который выполняет функция
первой строкой, опционально, может быть комментарий, так называемая docstring
в функциях может использоваться оператор return
он используется для прекращения работы функции и выхода из нее
чаще всего, оператор return возвращает какое-то значение
Примечание
Код функций, которые используются в этом подразделе, можно скопировать из файла create_func.py
Пример функции:
In [1]: def configure_intf(intf_name, ip, mask):
...: print('interface', intf_name)
...: print('ip address', ip, mask)
...:
Функция configure_intf создает конфигурацию интерфейса с указанным именем и IP-адресом. У функции есть три параметра: intf_name, ip, mask. При вызове функции в эти параметры попадут реальные данные.
Примечание
Когда функция создана, она ещё ничего не выполняет. Только при вызове функции действия, которые в ней перечислены, будут выполняться. Это чем-то похоже на ACL в сетевом оборудовании: при создании ACL в конфигурации, он ничего не делает до тех пор, пока не будет куда-то применен.
Вызов функции
При вызове функции нужно указать её имя и передать аргументы, если нужно.
Примечание
Параметры - это переменные, которые используются при создании функции. Аргументы - это фактические значения (данные), которые передаются функции при вызове.
Функция configure_intf ожидает при вызове три значения, потому что она была создана с тремя параметрами:
In [2]: configure_intf('F0/0', '10.1.1.1', '255.255.255.0')
interface F0/0
ip address 10.1.1.1 255.255.255.0
In [3]: configure_intf('Fa0/1', '94.150.197.1', '255.255.255.248')
interface Fa0/1
ip address 94.150.197.1 255.255.255.248
Текущий вариант функции configure_intf выводит команды на стандартный поток вывода, команды можно увидеть, но при этом результат функции нельзя сохранить в переменную.
Например, функция sorted не просто выводит результат сортировки на стандартный поток вывода, а возвращает его, поэтому его можно сохранить в переменную таким образом:
In [4]: items = [40, 2, 0, 22]
In [5]: sorted(items)
Out[5]: [0, 2, 22, 40]
In [6]: sorted_items = sorted(items)
In [7]: sorted_items
Out[7]: [0, 2, 22, 40]
Примечание
Обратите внимание на строку Out[5]
в ipython: таким образом ipython показывает,
что функция/метод что-то возвращает и показывает, что именно возвращает.
Если же попытаться записать в переменную результат функции configure_intf, в переменной окажется значение None:
In [8]: result = configure_intf('Fa0/0', '10.1.1.1', '255.255.255.0')
interface Fa0/0
ip address 10.1.1.1 255.255.255.0
In [9]: print(result)
None
Чтобы функция могла возвращать какое-то значение, надо использовать оператор return
.
Оператор return
Оператор return используется для возврата какого-то значения, и в то же время
он завершает работу функции.
Функция может возвращать любой объект Python.
По умолчанию, функция всегда возвращает None
.
Для того, чтобы функция configure_intf возвращала значение, которое потом можно,
например, присвоить переменной, надо использовать оператор return
:
In [10]: def configure_intf(intf_name, ip, mask):
...: config = f'interface {intf_name}\nip address {ip} {mask}'
...: return config
...:
In [11]: result = configure_intf('Fa0/0', '10.1.1.1', '255.255.255.0')
In [12]: print(result)
interface Fa0/0
ip address 10.1.1.1 255.255.255.0
In [13]: result
Out[13]: 'interface Fa0/0\nip address 10.1.1.1 255.255.255.0'
Теперь в переменой result находится строка с командами для настройки интерфейса.
В реальной жизни практически всегда функция будет возвращать какое-то значение. Вместе с тем можно использовать выражение print, чтобы дополнительно выводить какие-то сообщения.
Ещё один важный аспект работы оператора return: после return, функция завершает работу, а значит выражения, которые идут после return, не выполняются.
Например, в функции ниже, строка «Конфигурация готова» не будет выводиться, так как она стоит после return:
In [14]: def configure_intf(intf_name, ip, mask):
...: config = f'interface {intf_name}\nip address {ip} {mask}'
...: return config
...: print('Конфигурация готова')
...:
In [15]: configure_intf('Fa0/0', '10.1.1.1', '255.255.255.0')
Out[15]: 'interface Fa0/0\nip address 10.1.1.1 255.255.255.0'
Функция может возвращать несколько значений. В этом случае, они пишутся через запятую после оператора return. При этом фактически функция возвращает кортеж:
In [16]: def configure_intf(intf_name, ip, mask):
...: config_intf = f'interface {intf_name}\n'
...: config_ip = f'ip address {ip} {mask}'
...: return config_intf, config_ip
...:
In [17]: result = configure_intf('Fa0/0', '10.1.1.1', '255.255.255.0')
In [18]: result
Out[18]: ('interface Fa0/0\n', 'ip address 10.1.1.1 255.255.255.0')
In [19]: type(result)
Out[19]: tuple
In [20]: intf, ip_addr = configure_intf('Fa0/0', '10.1.1.1', '255.255.255.0')
In [21]: intf
Out[21]: 'interface Fa0/0\n'
In [22]: ip_addr
Out[22]: 'ip address 10.1.1.1 255.255.255.0'
Документация (docstring)
Первая строка в определении функции - это docstring, строка документации. Это комментарий, который используется как описание функции:
In [23]: def configure_intf(intf_name, ip, mask):
...: '''
...: Функция генерирует конфигурацию интерфейса
...: '''
...: config_intf = f'interface {intf_name}\n'
...: config_ip = f'ip address {ip} {mask}'
...: return config_intf, config_ip
...:
In [24]: configure_intf?
Signature: configure_intf(intf_name, ip, mask)
Docstring: Функция генерирует конфигурацию интерфейса
File: ~/repos/pyneng-examples-exercises/examples/06_control_structures/<ipython-input-23-2b2bd970db8f>
Type: function
Лучше не лениться писать краткие комментарии, которые описывают работу функции. Например, описать, что функция ожидает на вход, какого типа должны быть аргументы и что будет на выходе. Кроме того, лучше написать пару предложений о том, что делает функция. Это очень поможет, когда через месяц-два вы будете пытаться понять, что делает функция, которую вы же написали.