Программирование PC Python: функции Sat, March 29 2025  

Поделиться

Нашли опечатку?

Пожалуйста, сообщите об этом - просто выделите ошибочное слово или фразу и нажмите Shift Enter.


Python: функции Печать
Добавил(а) microsin   

На языке Python (как, впрочем, и на других языках программирования) функция это блок кода, который работает только когда его вызывают. Вы можете передать в функцию данные для обработки, и эти данные называются параметрами (или аргументами). Функция может изменять внешние глобальные переменные и ничего не возвращать (на других языках такие функции часто называют процедурами, или подпрограммами), либо может возвращать какую-нибудь переменную в качестве результата своих вычислений.

Функции придумали не просто так, они нужны для того, чтобы сделать программу понятней и эффективней. Вот основные цели, которым служит использование функций:

1. Функции позволяют разбить программу на отдельные простые, понятные для понимания части. В результате программа упрощается.
2. Функции позволяют скрыть детали реализации основного алгоритма. Это тоже способствует упрощению понимания алгоритма программы.
3. Повторное использование написанного кода.

[Создание функции]

На языке Python функция создается с помощью ключевого слова def, после которого через пробел идет имя функции, например:

def my_function():
   print("Привет из функции!")

Чтобы код в функции заработал, её нужно вызвать по имени:

def my_function():
  print("Hello from a function")
my_function()

Аргументы функции. В предыдущем примере у функции my_function не было параметров. Однако функция может принимать один или несколько параметров, указываемых в круглых скобках. Если параметров несколько, то они перечисляются через запятую.

def my_function(fparam):
   print('Функция печатает параметр:', fparam)
my_function(1) my_function(1+2+4) my_function("Просто текст")

Примечание: в документации Python часто аргументы функции сокращенно называют args.

Термины 'параметр' и 'аргумент' могут использоваться для обозначения одного и того же: это какая-то порция информации (переменная, объект), передаваемой в функцию.

С точки зрения функции:

- Параметр это локальная в контексте тела функции переменная, перечисленная внутри круглых скобках определения функции.
- Аргумент это значение, которое передается функции в момент её вызова.

Количество аргументов. По умолчанию функция должна быть вызвана с корректным количеством параметров, соответствующим её определению. Это значит, что если ваша функция ожидает 2 аргументов, то вы должны её вызвать с двумя аргументами, не больше и не меньше.

Например, эта функция ожидает 2 аргумента, и получает при вызове два аргумента:

def my_function(fparam1, fparam2):
   print(fparam1 + " " + fparam2)
my_function("Андрей", "Булавин")

Если вы попытаетесь передать в функцию my_function один параметр или три, то получите ошибку.

Произвольное количество параметров. Если вы не знаете, сколько параметров будет передано в функцию, то в определении функции добавьте звездочку перед именем параметра. Это позволяет передать в функцию кортеж аргументов (tuple), и к элементам кортежа можно обращаться как к элементам массива. Пример функции, которая напечатает все свои параметры через пробел:

def my_function(*fparam):
   for i in range(len(fparam)):
      print(fparam[i], '', end='')
   print()

.. или так, что то же самое:

def my_function(*fparam):
   for i in range(len(fparam)):
      print(fparam[i], '', end='')
   print()

Если эту функцию вызвать с разным количеством параметров:

my_function("Олег")
my_function("Олег", "Вокин")
my_function("Олег", "Вокин", "хороший человек")

.. то она напечатает:

Олег
Олег Вокин
Олег Вокин хороший человек

Ключевые (или именованные) аргументы. В обычном синтаксисе вызова функции вы должны передавать аргументы в функцию в таком же порядке, в котором они были перечислены в определении функции. Однако вы также можете передавать аргументы в функции с помощью синтаксиса key = value, в этом случае порядок следования аргументов при вызове не имеет значения. Здесь key это имя параметра, которому передается значение value, Например:

def my_function(fparam1, fparam2, fparam3):
   print('Третий параметр равен:', fparam3)

Эту функцию можно вызвать следующим образом. Обратите внимание, что порядок следования параметров в вызове отличается от определения my_function:

my_function(fparam2 = 'два', fparam3 = 'три', fparam1 = 'один')

Примечание: фраза "Keyword Arguments" (ключевые аргументы) в документации Python часто упоминается сокращением kwargs.

Произвольное количество ключевых аргументов. Если вы не знаете, сколько ключевых аргументов будет передаваться в функцию, то вы можете передать их в функцию, добавив в её определении две звездочки ** перед именем кортежа аргументов. Таким способом функция получит словарь аргументов (dictionary), и к нему можно будет обращаться соответствующим образом в теле функции:

def my_function(**fperson):
  print("Фамилия " + fperson["lname"])
my_function(fname = "Олег", lname = "Вокин")

Этот код напечатает:

Фамилия Вокин

Примечание: произвольное количество ключевых аргументов (Arbitrary Keyword Arguments) в документации Python часто сокращенно называют **kwargs.

Значение параметра по умолчанию. Следующий пример показывает, как использовать значение параметра по умолчанию. Если мы вызовем эту функцию без аргумента, то она будет использовать для него значение по умолчанию:

def my_function(country = "Россия"):
   print("Моя страна " + country)
my_function("Швеция") my_function("Индия") my_function() my_function("Бразилия")

Хороший пример использования именованного параметра по умолчанию - параметр end функции print. По умолчанию параметр end принимает значение '\n', именно по этому каждый вызов print переводит позицию вывода на новую строку:

print('Вывод первой строки')
print('Вывод второй строки')

Этот код ожидаемо напечатает:

Вывод первой строки
Вывод второй строки

Но если мы хотим продолжать печатать на одной и той же строке несколькими вызовами print, то необходимо в качестве параметра передать end='':

print('П', end='')
print('р', end='')
print('и', end='')
print('в', end='')
print('е', end='')
print('т', end='')

Этот код напечатает:

Привет

Список в качестве аргумента. В функцию можно передавать любые данные в качестве аргумента (строка, массив, число, список, словарь, и т. д.), и это будет обрабатываться в теле функции соответственно типу переданного аргумента.

Например, если вы передадите в аргумент список, то он так и останется списком внутри функции, например:

def my_function(food):
   for x in food:
      print(x)
fruits = ["яблоко", "банан", "вишня"] my_function(fruits)

Этот код напечатает содержимое списка fruits:

яблоко
банан
вишня

[Возврат значения из функции]

Чтобы функция могла возвратить значение, используйте в ней оператор return, например:

def my_function(x):
   return 5 * x

print(my_function(3))
print(my_function(5))
print(my_function(9))

Этот код выведет умноженное на 5 значение переданного в функцию аргумента:

15
25
45

[Оператор pass]

Определение функции не может быть пустым. Однако если по какой-то причине вы хотите оставить функцию без какой-либо реализации (временно создать заглушку функции, что может использоваться в целях отладки), то вы можете поместить в её тело оператор pass:

def myfunction():
   pass

[Только позиционные аргументы]

Вы можете указать, что у функции аргументы могут быть только позиционные, или указать, что они могут быть только ключевыми аргументами. Для того, чтобы аргументы были только позиционные, после имен аргументов добавьте , /:

def my_function(x, /):
   print(x)
my_function(3)

Если не указывать , /, то фактически разрешено использовать и ключевые аргументы, даже если функция ожидает позиционные аргументы, например:

def my_function(x):
  print(x)
my_function(x = 3)

Но если все-таки указать , /, то использование ключевых аргументов будет запрещено. Например, следующий код выдаст ошибку:

def my_function(x, /):
   print(x)
my_function(x = 3)

Traceback (most recent call last):
  File "c\temp\tt01.py", line 4, in < module>
    my_function(x = 3)
    ~~~~~~~~~~~^^^^^^^
TypeError: my_function() got some positional-only arguments passed
as keyword arguments: 'x'

Только ключевые аргументы. Чтобы указать, что функция может иметь только ключевые аргументы, добавьте *, перед аргументами:

def my_function(*, x):
  print(x)
my_function(x = 3)

Без указания *, разрешается использовать позиционные аргументы, даже если функция ожидает ключевые аргументы:

def my_function(x):
   print(x)
my_function(3)

Однако с указанием *, вы получите ошибку, если попробуете отправить в функцию позиционный аргумент:

def my_function(*, x):
   print(x)
my_function(3)

Traceback (most recent call last):
  File "e:\aaa5\3\tt01.py", line 4, in < module>
    my_function(3)
    ~~~~~~~~~~~^^^
TypeError: my_function() takes 0 positional arguments but 1 was given

Комбинирование Positional-Only и Keyword-Only аргументов. Вы можете комбинировать оба типа аргументов в одной и той же функции.

Любые аргументы перед /, являются только позиционными (positional-only), и любые аргументы после *, являются только ключевымиe( keyword-only). Например:

def my_function(a, b, /, *, c, d):
   print(a + b + c + d)
my_function(5, 6, c = 7, d = 8)

[Локальные и глобальные переменные]

Локальные переменные. Переменные, которые объявлены внутри функции, являются локальными, т. е. они доступны только внутри тела функции. Например, следующий код выдаст ошибку:

def init_values():
   a = 100
   b = 200
init_values()
print(a + b)

В следующем примере есть глобальная переменная a, и есть локальная переменная a, и это совершенно разные переменные, несмотря на то, что имена у них одинаковые:

def init_values():
   a = 100
a = 0 init_values()
print(a)

Этот код напечатает 0, потому что действие внутри init_values никак не повлияло на глобальную переменную a.

Параметр функции это тоже локальная переменная. Следующий пример тоже напечатает 0:

def init_values(a):
   a = 100
a = 0 init_values(a)
print(a)

Причина в том, что в функцию init_values передано значение глобальной переменной a, но не сама переменная, и не указатель на ней. Это не всегда так, что будет показано в следующем примере.

Изменение объектов, связанных с локальными переменными. Большой недостаток Python (если сравнивать с языком C) в том, что далеко не всегда хорошо видно, что передается в функцию - переменная или ссылка на неё (указатель). Если вы передадите в функцию объект, то будет передан не сам объект, а сслыка на него. Таким образом, действия внутри функции над переданным объектом приведут к тому, что будет изменена переменная глобального объекта. Например:

def append_100(v):
   v.append(100)
a = [] append_100(a)
print(a)

Этот код напечатает:

[100]

Вот еще пример:

def append_100(v):
   v.append(100)
   v = [5]
   v.append(7)
a = [] append_100(a)
print(a)

Этот пример также напечатает [100], несмотря на то, что в теле функции append_100 было присвание v = [5]. Это присваивание создало новую локальную переменную v, которая разорвала связь с указателем v, который был передан в функцию.

Глобальные переменные. Переменные, которые объявлены вне всяких функций, являются глобальными. Т. е. они доступны в любом месте программы, и внутри функций. В следующем примере переменная a является глобальной, и она доступна внутри функции print_val:

def print_val()
   print(a)
a = 5 print_val() # напечатает 5

Глобальные и локальные переменные. Нельзя смешивать внутри функции локальные и глобальные переменные под одинаковыми именами. Вот еще один пример:

def print_val():
   print(a)
   a = 10
   print(a)
a = 5 print_val()

Запуск этого кода выдаст ошибку:

Traceback (most recent call last):
  File "e:\aaa5\3\tt02.py", line 7, in < module>
    print_val()
    ~~~~~~~~~^^
  File "e:\aaa5\3\tt02.py", line 2, in print_val
    print(a)
          ^
UnboundLocalError: cannot access local variable 'a' where it is not
 associated with a value

Причина в следующем: если мы внутри функции пытаемся изменить переменную по такому же имени, что и глобальная переменная, то эта переменная считается локальной. Переменная внутри функции не может считаться в каком-то месте глобальной, а в другом месте локальной, поэтому при её присваивании внутри функции переменная становится локальной. Следовательно, первый вызов print(a) пытается напечатать локальную переменную a, которая еще не инициализирована, и поэтому появляется ошибка.

[Рекурсия]

Python также допускает рекурсию функции, т. е. разрешена ситуация, когда функция саму себя.

Рекурсия это общеизвестная концепция математики и программирования. Она означает, что функция вызывает саму себя. В результате получается выгода в том, что внутри функции может осуществляться цикл по обработке данных, пока все данные не будут обработаны, либо пока не будет достигнут нужный результат.

Разработчик должен быть очень внимателен с рекурсией, потому что можно очень просто написать функцию, которая никогда не завершится, или функция израсходует все ресурсы памяти и/или процессора. Однако, если рекурсия реализована корректно, она дает очень эффективный и математически элегантный код.

Следующий пример определяет функцию tri_recursion(), которая вызывает саму себя. В качестве данных используется переменная k, которая декрементируется в каждом рекурсивном вызове. Рекурсия заканчивается, когда условие не больше 0 (например, когда результат функции станет 0).

def tri_recursion(k):
   if(k > 0):
      result = k + tri_recursion(k - 1)
      print(result)
   else:
      result = 0
   return result
tri_recursion(6)

Этот код выведет следующее:

1
3
6
10
15
21

Новичку может потребоваться некоторое время, чтобы выяснить, как именно этот код работает, и лучший способ узнать это - протестировать и изменить его.

[Ссылки]

1. Python Functions site:w3schools.com.

 

Добавить комментарий


Защитный код
Обновить

Top of Page