Python 3 функции: Функции и их аргументы | Python 3 для начинающих и чайников

Содержание

Функции и их аргументы | Python 3 для начинающих и чайников

В этой статье я планирую рассказать о функциях, именных и анонимных, инструкциях def, return и lambda, обязательных и необязательных аргументах функции, функциях с произвольным числом аргументов.

Именные функции, инструкция def

Функция в python — объект, принимающий аргументы и возвращающий значение. Обычно функция определяется с помощью инструкции def.

Определим простейшую функцию:

def add(x, y):
    return x + y

Инструкция return говорит, что нужно вернуть значение. В нашем случае функция возвращает сумму x и y.

Теперь мы ее можем вызвать:

>>> add(1, 10)
11
>>> add('abc', 'def')
'abcdef'

Функция может быть любой сложности и возвращать любые объекты (списки, кортежи, и даже функции!):

>>> def newfunc(n):
...     def myfunc(x):
...         return x + n
...     return myfunc
...
>>> new = newfunc(100)  # new - это функция
>>> new(200)
300

Функция может и не заканчиваться инструкцией return, при этом функция вернет значение None:

>>> def func():
...     pass
...
>>> print(func())
None

Аргументы функции

Функция может принимать произвольное количество аргументов или не принимать их вовсе. Также распространены функции с произвольным числом аргументов, функции с позиционными и именованными аргументами, обязательными и необязательными.

>>> def func(a, b, c=2): # c - необязательный аргумент
...     return a + b + c
...
>>> func(1, 2)  # a = 1, b = 2, c = 2 (по умолчанию)
5
>>> func(1, 2, 3)  # a = 1, b = 2, c = 3
6
>>> func(a=1, b=3)  # a = 1, b = 3, c = 2
6
>>> func(a=3, c=6)  # a = 3, c = 6, b не определен
Traceback (most recent call last):
  File "", line 1, in
    func(a=3, c=6)
TypeError: func() takes at least 2 arguments (2 given)

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

>>> def func(*args):
...     return args
...
>>> func(1, 2, 3, 'abc')
(1, 2, 3, 'abc')
>>> func()
()
>>> func(1)
(1,)

Как видно из примера, args — это кортеж из всех переданных аргументов функции, и с переменной можно работать также, как и с кортежем.

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

>>> def func(**kwargs):
...     return kwargs
...
>>> func(a=1, b=2, c=3)
{'a': 1, 'c': 3, 'b': 2}
>>> func()
{}
>>> func(a='python')
{'a': 'python'}

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

Анонимные функции, инструкция lambda

Анонимные функции могут содержать лишь одно выражение, но и выполняются они быстрее. Анонимные функции создаются с помощью инструкции lambda. Кроме этого, их не обязательно присваивать переменной, как делали мы инструкцией def func():

>>> func = lambda x, y: x + y
>>> func(1, 2)
3
>>> func('a', 'b')
'ab'
>>> (lambda x, y: x + y)(1, 2)
3
>>> (lambda x, y: x + y)('a', 'b')
'ab'

lambda функции, в отличие от обычной, не требуется инструкция return, а в остальном, ведет себя точно так же:

>>> func = lambda *args: args
>>> func(1, 2, 3, 4)
(1, 2, 3, 4)

синтаксис, логика и применение ~ PythonRu

Введение

Определение

Вот пример простой функции:

def compute_surface(radius):
    from math import pi
    return pi * radius * radius

Для определения функции нужно всего лишь написать ключевое слово def перед ее именем, а после — поставить двоеточие. Следом идет блок инструкций.

Последняя строка в блоке инструкций может начинаться с return, если нужно вернуть какое-то значение. Если инструкции return нет, тогда по умолчанию функция будет возвращать объект None. Как в этом примере:

i = 0
def increment():
    global i
    i += 1

Функция инкрементирует глобальную переменную i и возвращает None (по умолчанию).

Вызовы

Для вызова функции, которая возвращает переменную, нужно ввести:

surface = compute_surface(1.)

Для вызова функции, которая ничего не возвращает:

increment()

Еще

Функцию можно записать в одну строку, если блок инструкций представляет собой простое выражение:

def sum(a, b): return a + b

Функции могут быть вложенными:

def func1(a, b):

    def inner_func(x):
        return x*x*x

    return inner_func(a) + inner_func(b)

Функции — это объекты, поэтому их можно присваивать переменным.

Инструкция return

Возврат простого значения

Аргументы можно использовать для изменения ввода и таким образом получать вывод функции. Но куда удобнее использовать инструкцию return, примеры которой уже встречались ранее. Если ее не написать, функция вернет значение None.

Возврат нескольких значений

Пока что функция возвращала только одно значение или не возвращала ничего (объект None). А как насчет нескольких значений? Этого можно добиться с помощью массива. Технически, это все еще один объект. Например:

def stats(data):
    """данные должны быть списком"""
    _sum = sum(data) 
    mean = _sum / float(len(data)) 
    variance = sum([(x-mean)**2/len(data) for x in data])
    return mean,variance   

m, v = stats([1, 2, 1])

Аргументы и параметры

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

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

def sum(x, y):
    return x + y

x и y — это параметры, а в этой:

sum(1, 2)

1 и 2 — аргументы.

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

def compute_surface(radius, pi=3.14159):
    return pi * radius * radius

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

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

def compute_surface(radius=1, pi):
    return pi * radius * radius

Для вызовов это работает похожим образом. Сначала нужно указывать все позиционные аргументы, а только потом необязательные:

S = compute_surface(10, pi=3.14)

На самом деле, следующий вызов корректен (можно конкретно указывать имя позиционного аргумента), но этот способ не пользуется популярностью:

S = compute_surface(radius=10, pi=3.14)

А этот вызов некорректен:

S = compute_surface(pi=3.14, 10)

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

def compute_surface2(radius=1, pi=3.14159):
    return pi * radius * radius
S = compute_surface2(radius=1, pi=3.14)
S = compute_surface2(pi=3.14, radius=10.)
S = compute_surface2(radius=10.)

Можно не указывать ключевые слова, но тогда порядок имеет значение. Он должен соответствовать порядку параметров в определении:

S = compute_surface2(10., 3.14)
S = compute_surface2(10.)

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

def f(a=1,b=2, c=3):
    return a + b + c

Второй аргумент можно пропустить:

f(1,,3)

Чтобы обойти эту проблему, можно использовать словарь:

params = {'a':10, 'b':20}
S = f(**params)

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

def inplace(x, mutable=[]):
   mutable.append(x)
   return mutable
res = inplace(1)
res = inplace(2)
print(inplace(3))
[1, 2, 3]
def inplace(x, lst=None):
   if lst is None: lst=[]
   lst.append()
   return lst

Еще один пример изменяемого объекта, значение которого поменялось при вызове:

def change_list(seq):
    seq[0] = 100
original = [0, 1, 2]
change_list(original)
original
[100, 1, 2]

Дабы не допустить изменения оригинальной последовательности, нужно передать копию изменяемого объекта:

original = [0, 1, 2]
change_list(original[:])
original
[0, 1, 2]

Указание произвольного количества аргументов

Позиционные аргументы

Иногда количество позиционных аргументов может быть переменным. Примерами таких функций могут быть max() и min(). Синтаксис для определения таких функций следующий:

def func(pos_params, *args):
    block statememt

При вызове функции нужно вводить команду следующим образом:

func(pos_params, arg1, arg2, ...)

Python обрабатывает позиционные аргументы следующим образом: подставляет обычные позиционные аргументы слева направо, а затем помещает остальные позиционные аргументы в кортеж (*args), который можно использовать в функции.

Вот так:

def add_mean(x, *data):
    return x + sum(data)/float(len(data))

add_mean(10,0,1,2,-1,0,-1,1,2)
10.5

Если лишние аргументы не указаны, значением по умолчанию будет пустой кортеж.

Произвольное количество аргументов-ключевых слов

Как и в случае с позиционными аргументами можно определять произвольное количество аргументов-ключевых слов следующим образом (в сочетании с произвольным числом необязательных аргументов из прошлого раздела):

def func(pos_params, *args, **kwargs):
    block statememt

При вызове функции нужно писать так:

func(pos_params, kw1=arg1, kw2=arg2, ...)

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

Есть функция:

def print_mean_sequences(**kwargs):
    def mean(data):
        return sum(data)/float(len(data))
    for k, v in kwargs.items():
        print k, mean(v)

print_mean_sequences(x=[1,2,3], y=[3,3,0])
y 2.0
x 2.0

Важно, что пользователь также может использовать словарь, но перед ним нужно ставить две звездочки (**):

print_mean_sequences(**{'x':[1,2,3], 'y':[3,3,0]})
y 2.0
x 2.0

Порядок вывода также не определен, потому что словарь не отсортирован.

Документирование функции

Определим функцию:

def sum(s,y): return x + y

Если изучить ее, обнаружатся два скрытых метода (которые начинаются с двух знаков нижнего подчеркивания), среди которых есть __doc__. Он нужен для настройки документации функции. Документация в Python называется docstring и может быть объединена с функцией следующим образом:

def sum(x, y):
    """Первая срока - заголовок

    Затем следует необязательная пустая строка и текст 
    документации.
    """
    return x+y

Команда docstring должна быть первой инструкцией после объявления функции. Ее потом можно будет извлекать или дополнять:

print(sum.__doc__)
sum.__doc__ += "some additional text"

Методы, функции и атрибуты, связанные с объектами функции

Если поискать доступные для функции атрибуты, то в списке окажутся следующие методы (в Python все является объектом — даже функция):

sum.func_closure   sum.func_defaults  sum.func_doc       sum.func_name
sum.func_code      sum.func_dict      sum.func_globals

И несколько скрытых методов, функций и атрибутов. Например, можно получить имя функции или модуля, в котором она определена:

>>> sum.__name__
"sum"
>>> sum.__module
"__main__"

Есть и другие. Вот те, которые не обсуждались:

sum.__call__          sum.__delattr__       sum.__getattribute__     sum.__setattr__
sum.__class__         sum.__dict__          sum.__globals__       sum.__new__           sum.__sizeof__
sum.__closure__       sum.__hash__          sum.__reduce__        sum.__str__
sum.__code__          sum.__format__        sum.__init__          sum.__reduce_ex__     sum.__subclasshook__
sum.__defaults__      sum.__get__           sum.__repr__

Рекурсивные функции

Рекурсия — это не особенность Python. Это общепринятая и часто используемая техника в Computer Science, когда функция вызывает сама себя. Самый известный пример — вычисление факториала n! = n * n — 1 * n -2 * … 2 *1. Зная, что 0! = 1, факториал можно записать следующим образом:

def factorial(n):
    if n != 0:
        return n * factorial(n-1)
    else:
        return 1

Другой распространенный пример — определение последовательности Фибоначчи:

f(0) = 1
f(1) = 1
f(n) = f(n-1) + f(n-2)

Рекурсивную функцию можно записать так:

def fibbonacci(n):
    if n >= 2:
        else:
    return 1

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

def factorial(n):
    assert n > 0
    if n != 0:
        return n * factorial(n-1)
    else:
        return 1

Важно!
Рекурсия позволяет писать простые и элегантные функции, но это не гарантирует эффективность и высокую скорость исполнения.

Если рекурсия содержит баги (например, длится бесконечно), функции может не хватить памяти. Задать максимальное значение рекурсий можно с помощью модуля sys.

Глобальная переменная

Вот уже знакомый пример с глобальной переменной:

i = 0
def increment():
    global i
    i += 1

Здесь функция увеличивает на 1 значение глобальной переменной i. Это способ изменять глобальную переменную, определенную вне функции. Без него функция не будет знать, что такое переменная i. Ключевое слово global можно вводить в любом месте, но переменную разрешается использовать только после ее объявления.

За редкими исключениями глобальные переменные лучше вообще не использовать.

Присвоение функции переменной

С существующей функцией func синтаксис максимально простой:

variable = func

Переменным также можно присваивать встроенные функции. Таким образом позже есть возможность вызывать функцию другим именем. Такой подход называется непрямым вызовом функции.

Менять название переменной также разрешается:

def func(x): return x
a1 = func
a1(10)
10
a2 = a1
a2()
10

В этом примере a1, a2 и func имеют один и тот же id. Они ссылаются на один объект.

Практический пример — рефакторинг существующего кода. Например, есть функция sq, которая вычисляет квадрат значения:

def sq(x): return x*x

Позже ее можно переименовать, используя более осмысленное имя. Первый вариант — просто сменить имя. Проблема в том, что если в другом месте кода используется sq, то этот участок не будет работать. Лучше просто добавить следующее выражение:

square = sq

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

dir = 3

Теперь к ней нельзя получить доступ, а это может стать проблемой. Чтобы вернуть ее обратно, нужно просто удалить переменную:

del dir
dir()

Анонимная функция: лямбда

Лямбда-функция — это короткая однострочная функция, которой даже не нужно имя давать. Такие выражения содержат лишь одну инструкцию, поэтому, например, if, for и while использовать нельзя. Их также можно присваивать переменным:

product = lambda x,y: x*y

В отличие от функций, здесь не используется ключевое слово return. Результат работы и так возвращается.

С помощью type() можно проверить тип:

>>> type(product)
function

На практике эти функции редко используются. Это всего лишь элегантный способ записи, когда она содержит одну инструкцию.

power = lambda x=1, y=2: x**y
square = power
square(5.)
25
power = lambda x,y,pow=2: x**pow + y
[power(x,2, 3) for x in [0,1,2]]
[2, 3, 10]

Изменяемые аргументы по умолчанию

>>> def foo(x=[]):
...     x.append(1)
...     print x
...
>>> foo()
[1]
>>> foo()
[1, 1]
>>> foo()
[1, 1, 1]

Вместо этого нужно использовать значение «не указано» и заменить на изменяемый объект по умолчанию:

>>> def foo(x=None):
...     if x is None:
...         x = []
...     x.append(1)
...     print x
>>> foo()
[1]
>>> foo()
[1]

Введение в Python. Часть 8. Функции

Функция в Python — это объект, принимающий аргументы и возвращающий значение. Со встроенными функциями вы уже сталкивались в предыдущих уроках. Например, когда когда мы хотели узнать сумму всех чисел в списке. Можете заглянуть в выпуск про списки.

Видео: Глеб Лиманский

Тогда мы использовали встроенную функцию sum(). На вход мы передавали аргумент — список с числами, а функция возвращала нам результат — сумму этих чисел.

Если бы такой функции в Python не существовало, то мы бы могли написать что-то вроде такого кода:

И это сразу несколько строчек кода, хоть и очень простого. А с функцией мы можем заменить их на всего лишь на одно слово, что гораздо удобнее. К тому же функция устроена более универсальным образом. Какой-бы список мы ей не передали, она все равно вернет нам сумму его элементов. Не важно как будут называться этот список и будет ли у него вообще название. Главное, чтобы в списке были числа!

Подписывайтесь на рассылку «Мастерской»

Вы узнаете о крутых инструментах для сбора, анализа и визуализации данных

А в нашем коде, где мы сами считаем сумму, речь идет о конкретном списке, который называется my_list. То есть без замены названия этот код нельзя будет использовать для другого списка. Поэтому, если бы функции суммы не существовало в питоне, то нам было бы удобнее написать ее самим. Давайте оформим наш кусочек кода в функцию.

Чтобы определить функцию используется конструкция def. Дальше пишем имя функции, скобки и двоеточие. После двоеточия вы кодом прописываете, что именно должна делать функция, а дальше с помощью return функция возвращает результат. А чтобы использовать функцию нужно написать ее название и в скобка и передать ей аргумент.

Вот так почти всегда будет выглядеть функция.

Но она не всегда должна что-то принимать на вход или что-то возвращать. Вот пример функции, которая просто здоровается — распечатывает «Hi!», но не принимает аргументов и ничего не возвращает. И если напишете print(say_hi()), то в ответе вы увидите None.

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

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

Также для функций существует отдельный вид аргументов. Один из них — необязательный аргумент. Например, мы хотим усовершенствовать нашу функцию say_hi_to(). Теперь она должна не просто здороваться с пользователем, но и заводить с ним небольшую беседу. Поэтому добавим в функцию необязательный аргумент small_talk.

По умолчанию мы назначили small_talk = «Как дела?». Когда мы будем вызывать функцию, нам не нужно указывать этот аргумент, он уже есть по умолчанию. Нам нужно лишь передать имя, дальше функция сама спросит пользователя «Как дела?».

Отдельно указывать аргумент small_talk при вывозе функции нужно только тогда, когда мы хотим внести в него какие-то изменения. Например, мы хотим, чтобы вместо «Как дела?» функция спросила что-то другое.

Давайте посмотрим, как функции могут использоваться на практике. Напишем функцию, которая будет очищать телефонный номер от пробелов, дефисов и скобок. Допустим у нас есть датасет, где содержатся данные о владельцах телефонных номеров. И нам нужно бы привести все телефоны к одному формату. Сначала мы будем писать функцию, а потом использовать ее для датасета. 

Допустим, наши данные у нас хранятся в виде подобного словаря — phone_book = {‘Alice’: ‘8-987-657 12 11’, ‘Bob’:’89012345678′, ‘Jack’:’8 (9 1 2) 3 4 5 6 7 8 9′}. Ключами тут являются имена, а значениями — телефоны, которые написаны по-разному: с пробелами, дефисами, скобками. Нам нужно к каждому из этих номеров приметь функцию clean_tel().

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

Такой список можно будет легко сохранить в табличку.

Анонимная функция

В Python есть анонимные функции — лямбды. Они подчиняющиеся более строгому, но более лаконичному синтаксису, чем обычные функции Python. И работаю быстрее. Анонимные функции могут содержать лишь одно выражение. Они создаются с помощью инструкции lambda. Кроме этого, их не обязательно присваивать переменной.

Чтобы было проще, давайте сначала напишем уже известную обычную функцию, а потом перепишем ее с помощью lambda. Вот пример функции, которая просто складывает два числа.

А вот как она выглядит, если переписать ее с помощью lambda.

После инструкции lambda нужно указать аргументы, а через двоеточие, что функция должна сделать с этими аргументами.

Лямбда-функцию не обязательно как-то называть. Ее можно вызвать и без имени. Нужно поместить функцию в скобки. И рядом же в скобках указать аргументы.

Кстати, и нашу функцию say_hi() тоже можно переписать с помощью lambda.

Это все основные принципы работы функций в Python. Если вы хотите прочитать о дополнительных возможностях функций, можете сделать это здесь. И, как всегда, тетрадка Jupyter Notebook с этого урока лежит на нашем GitHub.

Функции Python 3: значение, аргументы, вызов, переменные, списки — Python 3 | Data Science | Нейронные сети | AI

Содержание страницы

Функции – главный и самый важный способ организации и повторного использования кода в Python. Функций не может быть слишком много. 1 функция — это блок кода, который используется для выполнения одного связанного действия.

В Python есть два инструмента для создания функций: def и lambda.

Сначала рассмотрим def. К lambda функции вернемся позже.

Python предоставляет вам множество встроенных функций, таких как print() и т.д., но вы также можете создавать свои собственные функции. Эти функции называются пользовательскими функциями.

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

def my_function(x, y, z=1.5):
    if z > 1:
        return z * (x + y)
    else:
        return z / (x + y)

Ничто не мешает иметь в функции несколько предложений return. Если при выполнении достигнут конец функции, а предложение return не встретилось, то возвращается None.

У функции могут быть позиционные и именованные аргументы.

Именованные аргументы обычно используются для задания значений по умолчанию и необязательных аргументов.

В примере выше:

  • x и y – позиционные аргументы,
  • а z – именованный.

Следующие вызовы функции эквивалентны:

my_function(5, 6, z=0.7)
my_function(3.14, 7, 3.5)

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

Определение функции Python 3

Вы можете задать функции для реализации нужной вам функциональности. Вот простые правила для определения функции в Python.

  • Ключевое слово для определения функции: def, за которым следуют имя функции и круглые скобки () с параметрами.
  • Любые входные параметры или аргументы должны быть помещены в эти круглые скобки.
  • В качестве первой команды может быть необязательная конструкция — строка документации функции (эта часть функции — пояснение зачем функция создана, очень рекомендуется использовать для облегчения понимания кода при работе в команде или при повторном возвращении к коду через длительный промежуток времени).
  • Блок кода в каждой функции начинается с двоеточия : и имеет отступ.
  • Оператор return [выражение] возвращает результат из функции. Оператор return без аргументов аналогичен return None. Функции всегда возвращают значение, хотя бы None.

Синтаксис функции Python

def function_name( parameter1, parameter2 ):
   """function_docstring: функция Python предназначена для расчета ROI"""
   function_suite (algorithms, expressions)
   return [expression]

По умолчанию, параметры parameter1, parameter2 имеют позиционное поведение, и вам необходимо сообщить их в том же порядке, в котором они были определены.

Пример реализации функции

Следующая функция принимает строку в качестве входного параметра и печатает ее на стандартном экране.

def print_me( str ):
   """Выводит на печать переданную строку в эту функцию"""
   print(str)
   return

Вызов функции

В определении функции указывается имя функции, её параметры, а также тело функции (реализация требуемой функциональности).

Как только базовая структура функции создана, вы можете выполнить ее, вызвав ее из другой функции или непосредственно из Python prompt (командной оболочки). Ниже приведен пример вызова функции printme():

# Определение функции
def printme( str ):
    """This prints a passed string into this function"""
    print(str)
    return

# Теперь вы можете вызвать функцию printme
printme("I'm first call to user defined function!")
printme("Again second call to the same function")

Результат:

I'm first call to user defined function!
Again second call to the same function

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

  • Обязательные аргументы
  • Ключевые аргументы
  • Аргументы по умолчанию
  • Аргументы переменной длины

Обязательные (позиционные) аргументы

Позиционные аргументы: указываются простым перечислением

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

Чтобы вызвать функцию printme() , вам обязательно нужно передать один аргумент, иначе она выдаст следующую синтаксическую ошибку:

# Определение функции
def printme( str ):
   """This prints a passed string into this function"""
   print(str)
   return

# Теперь вы можете вызвать функцию printme
printme()

Ошибка (в функции Printme не указан аргумент):

Traceback (most recent call last):
  File "C:/Users/User/Desktop/CodePythonFunc.py", line 8, in <module>
    printme()
TypeError: printme() missing 1 required positional argument: 'str'

Правильно указать аргумент так:

# Определение функции
def printme( str ):
   """This prints a passed string into this function"""
   print(str)
   return

# Теперь вы можете вызвать функцию printme
printme("Текстовая переменная")

Ключевые аргументы

Ключевые аргументы: указываются перечислением ключ=значение

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

Это позволяет пропускать аргументы или размещать их не по порядку, поскольку интерпретатор Python может использовать предоставленные ключевые слова (ключи) для сопоставления значений с параметрами. Создадим ключевые слова для функции printinfo() следующими способами:

# Определение функции
def printinfo( name, age ):
   "This prints a passed info into this function"
   print("Name: " + name + "|Age: " + str(age))
   return

# Вызов функции printinfo
printinfo( age=23, name="Anton" )
printinfo( name="Alena", age=20 )

Результат:

Name: Anton|Age: 23
Name: Alena|Age: 20

Важно! Позиционные и ключевые аргументы могут быть скомбинированы в одной функции. Позиционные параметры всегда идут перед ключевыми.

Преимущества ключевых аргументов в функциях

  • Нет необходимости отслеживать порядок аргументов;
  • У ключевых параметров есть значение по умолчанию, которое можно не передавать.

Аргументы по умолчанию

Аргумент по умолчанию — это аргумент, который принимает значение по умолчанию (задается в описании функции), если при вызове функции аргументу не передается значение.

Следующий пример дает представление об аргументах по умолчанию, он печатает возраст по умолчанию, если он не был передан:

# Определение функции
def printinfo( name, age = 35 ):
   "This prints a passed info into this function"
   print("Name: " + name + "|Age: " + str(age))
   return

# Вызов функции printinfo
printinfo( age=19, name="Семен" )
printinfo( name="Николай" )

Результат:

Name: Семен|Age: 19
Name: Николай|Age: 35

Аргументы переменной длины

Передача кортежа в функцию — Использование *args в Python

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

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

Синтаксис для функции с аргументами переменной длины следующий:

def function_name([formal_args,] *args_tuple ):
    """function_docstring"""
    function_body
    return [expression]

Звездочка (*) ставится перед именем переменной, которая содержит в себе кортеж значений без ключевых слов. Кортеж является необязательным параметром.

Рассмотрим простой пример:

# Определение функции
def print_info( parametr_1, *var_tuple ):
   """Эта функция производит вывод переданных аргументов"""
   print("Output is: ")
   print(parametr_1)
   for elem in var_tuple:
      print(elem)
   return

# Вызов функции printinfo
print_info( 10 )
print_info( 70, 60, 50 )

Результат:

Output is: 
10
Output is: 
70
60
50

Еще один пример использования *args в функции Python:

def multiply(*args):
    z = 1
    for num in args:
        z *= num
    print(z)

multiply(4, 5)
multiply(10, 9)
multiply(2, 3, 4)
multiply(3, 5, 10, 6)

Результат:

20
90
24
900

Поскольку мы использовали *argsдля отправки списка аргументов переменной длины в нашу функцию, мы смогли передать столько аргументов, сколько пожелали, в вызовы функции.

С помощью *args вы можете создать более гибкий код, который принимает различное количество аргументов без ключевых слов в вашей функции.

Передачи словаря переменной длины с аргументами в функцию **kwargs

**kwargs — сокращение от “keyword arguments”

Форма двойной звездочки **kwargsиспользуется для передачи словарного словаря с аргументами переменной длины в функцию. Опять же, две звездочки ( **) являются здесь важным элементом, так как слово kwargsиспользуется условно, но не поддерживается языком.

Мол *args**kwargsможет принять столько аргументов, которые вы хотели бы привести к этому. Однако **kwargsотличается от того, *argsчто вам нужно будет назначить ключевые слова.

Во-первых, давайте просто распечатаем **kwargsаргументы, которые мы передаем функции. Мы создадим короткую функцию для этого:

def print_kwargs(**kwargs):
        print(kwargs)

print_kwargs(kwargs_1="Shark", kwargs_2=4.5, kwargs_3=True)

Давайте запустим программу выше и посмотрим на вывод:

{'kwargs_1': 'Shark', 'kwargs_2': 4.5, 'kwargs_3': True}

В зависимости от версии Python 3, которую вы используете в данный момент, тип данных словаря может быть неупорядоченным. В Python 3.6 и выше вы получите пары ключ-значение по порядку, но в более ранних версиях пары будут выводиться в случайном порядке.

Важно отметить, что kwargsсозданный словарь создан, и мы можем работать с ним так же, как мы можем работать с другими словарями.

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

def print_values(**kwargs):
    for key, value in kwargs.items():
        print("The value of {} is {}".format(key, value))

print_values(my_name="Sammy", your_name="Casey")

Результат:

The value of my_name is Sammy
The value of your_name is Casey

Использование **kwargsдает нам гибкость в использовании ключевых аргументов в нашей программе. Когда мы используем **kwargsв качестве параметра, нам не нужно знать, сколько аргументов мы в конечном итоге хотели бы передать функции.

Использование *args и **kwargs в вызовах функций

Мы также можем использовать *argsи **kwargsдля передачи аргументов в функции.

Сначала давайте рассмотрим пример с *args.

def some_args(arg_1, arg_2, arg_3):
    print("arg_1:", arg_1)
    print("arg_2:", arg_2)
    print("arg_3:", arg_3)

args = ("Sammy", "Casey", "Alex")
some_args(*args)

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

Когда мы запустим код, мы получим следующий вывод:

arg_1: Sammy
arg_2: Casey
arg_3: Alex

Мы также можем изменить вышеприведенную программу для типа данных итеративного списка с другим именем переменной. Давайте также объединим *argsсинтаксис с именованным параметром:

def some_args(arg_1, arg_2, arg_3):
    print("arg_1:", arg_1)
    print("arg_2:", arg_2)
    print("arg_3:", arg_3)

my_list = [2, 3]
some_args(1, *my_list)

Если мы запустим программу выше, она выдаст следующий вывод:

arg_1: 1
arg_2: 2
arg_3: 3

Аналогично, **kwargsаргументы с ключевым словом могут использоваться для вызова функции. Мы установим переменную, равную словарю с 3 парами ключ-значение (мы будем использовать kwargsздесь, но она может называться как угодно), и передадим ее функции с 3 аргументами:

def some_kwargs(kwarg_1, kwarg_2, kwarg_3):
    print("kwarg_1:", kwarg_1)
    print("kwarg_2:", kwarg_2)
    print("kwarg_3:", kwarg_3)

kwargs = {"kwarg_1": "Val", "kwarg_2": "Harper", "kwarg_3": "Remy"}
some_kwargs(**kwargs)

Результат:

kwarg_1: Val
kwarg_2: Harper
kwarg_3: Remy

Мы можем использовать специальный синтаксис *args и **kwargs внутри определения функции, чтобы передать переменное число аргументов функции.

Создание функций, которые принимают *argsи **kwargsлучше всего использовать в ситуациях, когда вы ожидаете, что количество входов в списке аргументов останется относительно небольшим. Использование *argsи **kwargsв первую очередь для обеспечения удобочитаемости и удобства, но следует делать с осторожностью.

Комбинирование параметров *args и **kwargs в функции

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

def func(*args, **kwargs):
    """Функция примет любые параметры и выведет их на печать"""
    for elem in args:                   # Перебираем список с переданными параметрами
        print(elem, end=" ")
    for key, value in kwargs.items():   # Перебираем словарь с переданными параметрами
        print("{0} => {1}".format(key, value), end=" ")
    print("") #Перенос строки

func(35, 10, a=1, b=2, c=3) # Выведет: 35 10 a => 1 c => 3 b => 2
func(10)                    # Выведет: 10
func(3, a=1, b=2)           # Выведет: a => 1 b => 2

Результат:

35 10 a => 1 b => 2 c => 3 
10 
3 a => 1 b => 2 

Еще один пример использования комбинации *args & **kwargs:

# Описываем функцию
def echo(*args, **kwargs):
    print(args, kwargs)

# Задаем список
args = (10, 20)
# Задаем словарь
kwargs = {'a':30, 'b':40}

#Вызываем функцию
echo(*args, **kwargs)

Результат:

(10, 20) {'a': 30, 'b': 40}

Порядок аргументов в функции Python

Аргументы внутри вызова функции должны стоять в определенном порядке:

  1. Позиционные аргументы (arg_1, arg_2)
  2. *args
  3. Ключевые аргументы (kw_1=»значение 1″, kw_2=»значение 2″)
  4. **kwargs

Рассмотрим детальный пример с использованием всех функций:

def function_print(arg_1, arg_2, *args, kw_1="значение 1", kw_2="значение 2", **kwargs):
    """ Обобщенный пример вывода всех аргументов, переданных функции """
    print("===Позиционные аргументы===")
    print(str(arg_1) + "," + str(arg_2))
    print("===*args===")
    for elem in args: # Перебираем список с переданными параметрами
        print(elem, end=" ")
    print("") #Перенос строки
    print("===Ключевые аргументы===")
    print(kw_1 + "," + kw_2)
    print("===**kwargs===")
    for key, value in kwargs.items(): # Перебираем словарь с переданными параметрами
        print("{0} => {1}".format(key, value), end=" ")
    print("") #Перенос строки


function_print(1, 2, 4, kw_2="Иван", var1=4)

Результат:

===Позиционные аргументы===
1,2
===*args===
4 
===Ключевые аргументы===
значение 1,Иван
===**kwargs===
var1 => 4 

Передача списка (list) по ссылке в функцию

def myfunction (list):
    list.append(40)
    print ("Modified list inside a function: ", list)
    return

mylist=[10,20,30]
myfunction(mylist)
print(mylist)

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

Modified list inside a function: [10, 20, 30, 40]
[10, 20, 30, 40]

Область действия переменной — область видимости переменных

Переменные в программе могут быть доступны или недоступны в разных местах этой программы. Это зависит от того, где вы объявили переменную.

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

  • Глобальные переменные
  • Локальные переменные

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

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

Переменные внутри функции – локальные. Поиск переменных: сперва среди локальных, потом среди глобальных.

Рассмотрим следующую функцию:

def func():
    a = []
    for i in range(5):
        a.append(i)

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

a = []
def func():
    for i in range(5):
        a.append(i)

Присваивать значение глобальной переменной внутри функции допустимо, но такие переменные должны быть объявлены глобальными с помощью ключевого слова global:

a = None

def bind_a_variable():
    global a
    a = []

bind_a_variable()
print a

Результат:

[]

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

def outer_function(x, y, z):
    def inner_function(a, b, c):
        pass
    pass

Здесь функция inner_function не существует, пока не вызвана функция outer_function. Как только outer_function завершает выполнение, inner_function уничтожается.

Не рекомендуется злоупотреблять ключевым словом global. Обычно глобальные переменные служат для хранения состояния системы. Если вы понимаете, что пользуетесь ими слишком часто, то стоит подумать о переходе к объектно-ориентированному программированию (использовать классы).

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

Строго говоря, любая функция локальна в какой-то области видимости, хотя это может быть и область видимости на уровне модуля.

Возврат нескольких значений из одной функции

В Python существует возможность возвращать из функции несколько значений.

Вот простой пример:

def f():
    a = 5
    b = 6
    c = 7
    return a, b, c
var1, var2, var3 = f()

print("var1={0} var2={1} var3={2}".format(var1, var2, var3))

Результат:

var1=5 var2=6 var3=7

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

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

Этот пример можно было бы записать и так:

def f():
    a = 5
    b = 6
    c = 7
    return a, b, c
return_value = f()

print(return_value)

Результат:

(5, 6, 7)

В таком случае return_value было бы кортежем, содержащим все три возвращенные переменные.

Иногда разумнее возвращать несколько значений не в виде кортежа, а в виде словаря:

def f():
    a = 5
    b = 6
    c = 7
    return {'a' : a, 'b' : b, 'c' : c}

return_value = f()

print(return_value)

Результат:

{'a': 5, 'b': 6, 'c': 7}

Функции являются объектами

Поскольку функции в Python – объекты, становятся возможны многие конструкции, которые в других языках выразить трудно. Пусть, например, мы производим очистку данных и должны применить ряд преобразований к следующему списку строк:

states = [' Alabama ', 'Georgia!', 'Georgia', 'georgia', 'FlOrIda', 'south carolina##', 'West virginia?']

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

Первая попытка могла бы выглядеть так:

import re # Модуль регулярных выражений

def clean_strings(strings):
    result = []
    for value in strings:
        value = value.strip()
        value = re.sub('[!#?]', '', value) # удалить знаки препинания
        value = value.title()
        result.append(value)
    return result

states = [' Alabama ', 'Georgia!', 'Georgia', 'georgia', 'FlOrIda', 'south carolina##', 'West virginia?']

states = clean_strings(states)

print(states)

Результат:

['Alabama', 'Georgia', 'Georgia', 'Georgia', 'Florida', 'South Carolina', 'West Virginia']

Другой подход, который иногда бывает полезен, – составить список операций, которые необходимо применить к набору строк:

import re # Модуль регулярных выражений

def remove_punctuation(value):
    return re.sub('[!#?]', '', value)

def clean_strings(strings, ops):
    result = []
    for value in strings:
        for function in ops:
            value = function(value)
        result.append(value)
    return result

clean_ops = [str.strip, remove_punctuation, str.title]
states = [' Alabama ', 'Georgia!', 'Georgia', 'georgia', 'FlOrIda', 'south carolina##', 'West virginia?']

states = clean_strings(states, clean_ops)

print(states)

Результат:

['Alabama', 'Georgia', 'Georgia', 'Georgia', 'Florida', 'South Carolina', 'West Virginia']

Подобный функциональный подход позволяет задать способ модификации строк на очень высоком уровне. Степень повторной используемости функции clean_strings определенно возросла!

Функции можно передавать в качестве аргументов другим функциям, например встроенной функции map, которая применяет переданную функцию к коллекции:

import re # Модуль регулярных выражений

def remove_punctuation(value):
    return re.sub('[!#?]', '', value)

states = [' Alabama ', 'Georgia!', 'Georgia', 'georgia', 'FlOrIda', 'south carolina##', 'West virginia?']

states = list(map(remove_punctuation, states))
states = list(map(str.strip, states))
states = list(map(str.title, states))

print(states)

Результат:

['Alabama', 'Georgia', 'Georgia', 'Georgia', 'Florida', 'South Carolina', 'West Virginia']

Анонимные функции или Лямбда-функции. Lambda Function Python 3

  • Лямбда-функции позволяют создавать «встроенные» функции, которые полезны для функционального программирования. Например, с Map, Filter или Reduce.
  • Lambda — это инструмент для создания обработчиков обратного вызова (callback handlers).

Lambda Function — это анонимная однострочная функция, которая возвращает всегда 1 результат.

Определяются они с помощью ключевого слова lambda

ИмяФункции = lambda переменная_1, переменная_2, …, переменная_N: <выражение, которое использует переменные>

Например, функция equiv_anon:

equiv_anon = lambda x: x * 2

эквивалентна функции short_function:

def short_function(x):
    return x * 2

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

Рассмотрим такой простенький пример:

def apply_to_list(some_list, f):
    return [f(x) for x in some_list]

ints = [4, 0, 1, 5, 6]

result = apply_to_list(ints, lambda x: x * 2)

print(result)

Результат:

[8, 0, 2, 10, 12]

Можно было бы, конечно, написать [x * 2 for x in ints], но в данном случае нам удалось передать функции apply_to_list пользовательский оператор.

Еще пример: пусть требуется отсортировать коллекцию строк по количеству различных букв в строке.

Для этого можно передать лямбда-функцию методу списка sort:

strings = ['foo', 'card', 'bar', 'aaaa', 'abab']

strings.sort(key=lambda x: len(set(list(x))))

print(strings)

Результат:

['aaaa', 'foo', 'abab', 'bar', 'card']

Для чего хороша лямбда-функция? Зачем нужная lambda function в Python?

Ответ:

  • Нам не нужна лямбда функция, мы могли бы обойтись без нее. Но…
  • Есть определенные ситуации, когда это удобно — lambda делает написание кода немного легче, а написанный код — немного чище.

Какие ситуации?

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

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

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

Но предположим, что вам нужно создать функцию, которая будет использоваться только один раз — вызываться только из одного места в вашем приложении. Ну, во-первых, вам не нужно давать имя функции. Это может быть «анонимно». И вы можете просто определить его прямо там, где вы хотите его использовать. Вот где лямбда полезна.

Еще один пример использования lambda функции:

colors = ["Goldenrod", "Purple", "Salmon", "Turquoise", "Cyan"]

normalized_colors = list(map(lambda s: s.casefold(), colors))

print(normalized_colors)

Результат:

['goldenrod', 'purple', 'salmon', 'turquoise', 'cyan']

Неправильное использование: именование лямбда-выражений

PEP8, официальное руководство по стилю Python, советует никогда не писать такой код:

normalize_case = lambda s: s.casefold()

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

Если вы хотите создать однострочную функцию и сохранить ее в переменной, вы должны использовать defвместо этого:

def normalize_case(s): return s.casefold()

PEP8 рекомендует это, потому что именованные функции — это обычная и понятная вещь. Именованная функция также имеет следующее преимущество: назначая нашей функции правильное имя, Вы упрощаете отладку кода. В отличие от функций, определенных с помощью def, лямбда-функции никогда не имеют имени (это всегда <lambda>).

Если вы хотите создать функцию и сохранить ее в переменной, определите свою функцию с помощью def . Это именно то, для чего существует именованная функция. Не имеет значения, является ли ваша функция одной строкой кода или вы определяете функцию внутри другой функции, def отлично работает для этих случаев использования.

Неправильное использование: ненужные вызовы функций

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

Например, возьмем этот код:

sorted_numbers = sorted(numbers, key=lambda n: abs(n))

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

Поскольку abs (которая возвращает абсолютное значение числа) является функцией и все функции могут быть переданы, мы могли бы написать приведенный выше код следующим образом:

sorted_numbers = sorted(numbers, key=abs)

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

pairs = [(4, 11), (8, 8), (5, 7), (11, 3)]
sorted_by_smallest = sorted(pairs, key=lambda items: min(items))

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

pairs = [(4, 11), (8, 8), (5, 7), (11, 3)]
sorted_by_smallest = sorted(pairs, key=min)

Вам не нужна лямбда-функция, если у вас уже есть другая функция, которая делает то, что вы хотите.

Замыкания: функции, возвращающие функции. Динамически сгенерированная функция

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

Вот очень простой пример:

def make_closure(a):
    def closure():
        print('Я знаю секрет: %d' % a)
    return closure

closure = make_closure(5)
closure()

Результат:

Я знаю секрет: 5

Разница между замыканием и обычной функцией Python состоит в том, что замыкание сохраняет доступ к пространству имен (функции), в котором было создано, даже если создавшая ее функция уже завершилась.

Так, в примере выше, возвращенное замыкание печатает строку «Я знаю секрет: 5», в какой бы момент ее ни вызвать. Хотя обычно создают замыкания со статическим внутренним состоянием (в данном случае только значение a), ничто не мешает включить в состав состояния изменяемый объект – словарь, множество, список – и затем модифицировать его.

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

def make_watcher():
    have_seen = {}

    def has_been_seen(x):
        if x in have_seen:
            return True
        else:
            have_seen[x] = True
        return False

    return has_been_seen

watcher = make_watcher()

vals = [5, 6, 1, 5, 1, 6, 3, 5]

print([watcher(x) for x in vals])

Результат:

[False, False, False, True, True, True, False, True]

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

def make_counter():
    count = [0]

    def counter():
        # увеличить счетчик и вернуть новое значение
        count[0] += 1
        return count[0]
    return counter

counter = make_counter()
print(counter())

Результат:

1

Возникает вопрос, зачем все это нужно? На практике можно написать очень общую функцию с кучей параметров, а затем изготовить на ее основе более простые специализированные функции.

Вот пример функции форматирования строк:

def format_and_pad(template, space):
    def formatter(x):
        return (template % x).rjust(space)
    return formatter

fmt = format_and_pad('%.4f', 15)
print(fmt(1.756))

Результат:

'         1.7560'

Каррирование: частичное фиксирование аргументов функции

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

Пусть, например, имеется тривиальная функция сложения двух чисел:

def add_numbers(x, y):
    return x + y

Мы можем породить на ее основе новую функцию одной переменной, add_five, которая прибавляет к своему аргументу 5:

add_five = lambda y: add_numbers(5, y)

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

Теперь запустим полный код:

def add_numbers(x, y):
    return x + y

add_five = lambda y: add_numbers(5, y)

print(add_five(10))

Результат:

15

Стандартный модуль functools упрощает эту процедуру за счет функции partial:

from functools import partial

def add_numbers(x, y):
    return x + y

add_five = partial(add_numbers, 5)

print(add_five(10))

Также вернет 15

При обсуждении библиотеки pandas мы будем пользоваться этой техникой для создания специализированных функций преобразования временных рядов:

# вычислить скользящее среднее временного ряда x за 60 дней
ma60 = lambda x: pandas.rolling_mean(x, 60)
# вычислить скользящие средние за 60 дней всех временных рядов в data
data.apply(ma60)

5
1
голос

Рейтинг статьи

Работаем с функциями в Python

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

def a_function():
print(«You just created a function!»)

def a_function():

    print(«You just created a function!»)

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

a_function() # You just created a function!

a_function() # You just created a function!

Просто, не так ли?

Пустая функция (stub)

Иногда, когда вы пишете какой-нибудь код, вам нужно просто ввести определения функции, которое не содержит в себе код. Я сделал небольшой набросок, который поможет вам увидеть, каким будет ваше приложение. Вот пример:

def empty_function():
pass

def empty_function():

    pass

А вот здесь кое-что новенькое: оператор pass. Это пустая операция, это означает, что когда оператор pass выполняется, не происходит ничего.

Передача аргументов функции

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

def add(a, b):
return a + b

print( add(1, 2) ) # 3

def add(a, b):

    return a + b

 

print( add(1, 2) ) # 3

Каждая функция выдает определенный результат. Если вы не указываете на выдачу конкретного результата, она, тем не менее, выдаст результат None (ничего). В нашем примере мы указали выдать результат a + b. Как вы видите, мы можем вызвать функцию путем передачи двух значений. Если вы передали недостаточно, или слишком много аргументов для данной функции, вы получите ошибку:

add(1)

Traceback (most recent call last):
File «<string>», line 1, in <fragment>
TypeError: add() takes exactly 2 arguments (1 given)

add(1)

 

Traceback (most recent call last):

    File «<string>», line 1, in <fragment>

TypeError: add() takes exactly 2 arguments (1 given)

Вы также можете вызвать функцию, указав наименование аргументов:

print( add(a = 2, b = 3) ) # 5

total = add(b = 4, a = 5)
print(total) # 9

print( add(a = 2, b = 3) ) # 5

 

total = add(b = 4, a = 5)

print(total) # 9

Стоит отметить, что не важно, в каком порядке вы будете передавать аргументы функции до тех пор, как они называются корректно. Во втором примере мы назначили результат функции переменной под названием total. Это стандартный путь вызова функции в случае, если вы хотите дальше использовать её результат.

Вы, возможно, подумаете: «А что, собственно, произойдет, если мы укажем аргументы, но они названы неправильно? Это сработает?» Давайте попробуем на примере:

add(c=5, d=2)

Traceback (most recent call last):
File «<string>», line 1, in <fragment>
TypeError: add() got an unexpected keyword argument ‘c’

add(c=5, d=2)

 

Traceback (most recent call last):

    File «<string>», line 1, in <fragment>

TypeError: add() got an unexpected keyword argument ‘c’

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

Есть вопросы по Python?

На нашем форуме вы можете задать любой вопрос и получить ответ от всего нашего сообщества!

Telegram Чат & Канал

Вступите в наш дружный чат по Python и начните общение с единомышленниками! Станьте частью большого сообщества!

Паблик VK

Одно из самых больших сообществ по Python в социальной сети ВК. Видео уроки и книги для вас!

Ключевые аргументы

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

def keyword_function(a=1, b=2):
return a+b

print( keyword_function(b=4, a=5) ) # 9

def keyword_function(a=1, b=2):

    return a+b

 

print( keyword_function(b=4, a=5) ) # 9

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

Функция вернулась к нам с числом 3. Почему? Причина заключается в том, что а и b по умолчанию имеют значение 1 и 2 соответственно. Теперь попробуем создать функцию, которая имеет обычный аргумент, и несколько ключевых аргументов:

def mixed_function(a, b=2, c=3):
return a+b+c

mixed_function(b=4, c=5)

Traceback (most recent call last):
File «<string>», line 1, in <fragment>
TypeError: mixed_function() takes at least 1 argument (2 given)

def mixed_function(a, b=2, c=3):

    return a+b+c

 

mixed_function(b=4, c=5)

 

Traceback (most recent call last):

    File «<string>», line 1, in <fragment>

TypeError: mixed_function() takes at least 1 argument (2 given)

print( mixed_function(1, b=4, c=5) ) # 10

print( mixed_function(1) ) # 6

print( mixed_function(1, b=4, c=5) ) # 10

 

print( mixed_function(1) ) # 6

Выше мы описали три возможных случая. Проанализируем каждый из них. В первом примере мы попробовали вызвать функцию, используя только ключевые аргументы. Это дало нам только ошибку. Traceback указывает на то, что наша функция принимает, по крайней мере, один аргумент, но в примере было указано два аргумента. Что же произошло? Дело в том, что первый аргумент необходим, потому что он ни на что не указывает, так что, когда мы вызываем функцию только с ключевыми аргументами, это вызывает ошибку. Во втором примере мы вызвали смешанную функцию, с тремя значениями, два из которых имеют название. Это работает, и выдает нам ожидаемый результат: 1+4+5=10. Третий пример показывает, что происходит, если мы вызываем функцию, указывая только на одно значение, которое не рассматривается как значение по умолчанию. Это работает, если мы берем 1, и суммируем её к двум значениям по умолчанию: 2 и 3, чтобы получить результат 6! Удивительно, не так ли?

*args и **kwargs

Вы также можете настроить функцию на прием любого количества аргументов, или ключевых аргументов, при помощи особого синтаксиса. Чтобы получить бесконечное количество аргументов, мы используем *args, а чтобы получить бесконечное количество ключевых аргументов, мы используем *kwargs. Сами слова “args” и “kwargs” не так важны. Это просто сокращение. Вы можете назвать их *lol и *omg, и они будут работать таким же образом. Главное здесь – это количество звездочек. Обратите внимание: в дополнение к конвенциям *args и *kwargs, вы также, время от времени, будете видеть andkw. Давайте взглянем на следующий пример:

def many(*args, **kwargs):
print( args )
print( kwargs )

many(1, 2, 3, name=»Mike», job=»programmer»)

# Результат:
# (1, 2, 3)
# {‘job’: ‘programmer’, ‘name’: ‘Mike’}

def many(*args, **kwargs):

    print( args )

    print( kwargs )

 

many(1, 2, 3, name=»Mike», job=»programmer»)

 

# Результат:

# (1, 2, 3)

# {‘job’: ‘programmer’, ‘name’: ‘Mike’}

Сначала мы создали нашу функцию, при помощи нового синтаксиса, после чего мы вызвали его при помощи трех обычных аргументов, и двух ключевых аргументов. Функция показывает нам два типа аргументов. Как мы видим, параметр args превращается в кортеж, а kwargs – в словарь. Вы встретите такой тип кодинга, если взгляните на исходный код Пайтона, или в один из сторонних пакетов Пайтон.

Область видимость и глобальные переменные

Концепт области (scope) в Пайтон такой же, как и в большей части языков программирования. Область видимости указывает нам, когда и где переменная может быть использована. Если мы определяем переменные внутри функции, эти переменные могут быть использованы только внутри это функции. Когда функция заканчиваются, их можно больше не использовать, так как они находятся вне области видимости. Давайте взглянем на пример:

def function_a():
a = 1
b = 2
return a+b

def function_b():
c = 3
return a+c

print( function_a() )
print( function_b() )

def function_a():

    a = 1

    b = 2

    return a+b

 

 

def function_b():

    c = 3

    return a+c

 

print( function_a() )

print( function_b() )

Если вы запустите этот код, вы получите ошибку:

NameError: global name ‘a’ is not defined

NameError: global name ‘a’ is not defined

Это вызвано тем, что переменная определенна только внутри первой функции, но не во второй. Вы можете обойти этот момент, указав в Пайтоне, что переменная а – глобальная (global). Давайте взглянем на то, как это работает:

def function_a():
global a
a = 1
b = 2
return a+b

def function_b():
c = 3
return a+c

print( function_a() )
print( function_b() )

def function_a():

    global a

    a = 1

    b = 2

    return a+b

 

 

def function_b():

    c = 3

    return a+c

 

print( function_a() )

print( function_b() )

Этот код работает, так как мы указали Пайтону сделать а – глобальной переменной, а это значит, что она работает где-либо в программе. Из этого вытекает, что это настолько же хорошая идея, насколько и плохая. Причина, по которой эта идея – плохая в том, что нам становится трудно сказать, когда и где переменная была определена. Другая проблема заключается в следующем: когда мы определяем «а» как глобальную в одном месте, мы можем случайно переопределить её значение в другом, что может вызвать логическую ошибку, которую не просто исправить.

Советы в написании кода

Одна из самых больших проблем для молодых программистов – это усвоить правило «не повторяй сам себя». Суть в том, что вы не должны писать один и тот же код несколько раз. Когда вы это делаете, вы знаете, что кусок кода должен идти в функцию. Одна из основных причин для этого заключается в том, что вам, вероятно, придется снова изменить этот фрагмент кода в будущем, и если он будет находиться в нескольких местах, вам нужно будет помнить, где все эти местоположения И изменить их.

Сайт doctorsmm.com предлагает Вам персональные предложения по покупке лайков в ВК к постам и публикациям. Здесь Вы найдете дешевые цены на услуги, а также различные критерии, подходящие к любой ситуации. На сервисе также доступно приобретение репостов, голосов в голосования и опросы сети.

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

Подведем итоги

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

Являюсь администратором нескольких порталов по обучению языков программирования Python, Golang и Kotlin. В составе небольшой команды единомышленников, мы занимаемся популяризацией языков программирования на русскоязычную аудиторию. Большая часть статей была адаптирована нами на русский язык и распространяется бесплатно.

E-mail: [email protected]

Образование
Universitatea Tehnică a Moldovei (utm.md)

  • 2014 — 2018 Технический Университет Молдовы, ИТ-Инженер. Тема дипломной работы «Автоматизация покупки и продажи криптовалюты используя технический анализ»
  • 2018 — 2020 Технический Университет Молдовы, Магистр, Магистерская диссертация «Идентификация человека в киберпространстве по фотографии лица»

Функции в программировании. Курс «Python. Введение в программирование»

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

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

Существует множество встроенных в язык программирования функций. С некоторыми такими в Python мы уже сталкивались. Это print(), input(), int(), float(), str(), type(). Код их тела нам не виден, он где-то «спрятан внутри языка». Нам же предоставляется только интерфейс – имя функции.

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

Предположим, надо три раза подряд запрашивать на ввод пару чисел и складывать их. С этой целью можно использовать цикл:

i = 0
while i < 3:
    a = int(input())
    b = int(input())
    print(a+b)
    i += 1

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

print("Сколько бананов и ананасов для обезьян?")
a = int(input())
b = int(input())
print("Всего", a+b, "шт.")
 
print("Сколько жуков и червей для ежей?")
a = int(input())
b = int(input())
print("Всего", a+b, "шт.")
 
print("Сколько рыб и моллюсков для выдр?")
a = int(input())
b = int(input())
print("Всего", a+b, "шт.")

Пример исполнения программы:

Сколько бананов и ананасов для обезьян?
15
5
Всего 20 шт.
Сколько жуков и червей для ежей?
50
12
Всего 62 шт.
Сколько рыб и моллюсков для выдр?
16
8
Всего 24 шт.

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

Определение функции. Оператор def

В языке программирования Python функции определяются с помощью оператора def. Рассмотрим код:

def countFood():
    a = int(input())
    b = int(input())
    print("Всего", a+b, "шт.")

Это пример определения функции. Как и другие сложные инструкции вроде условного оператора и циклов функция состоит из заголовка и тела. Заголовок оканчивается двоеточием и переходом на новую строку. Тело имеет отступ.

Ключевое слово def сообщает интерпретатору, что перед ним определение функции. За def следует имя функции. Оно может быть любым, также как и всякий идентификатор, например, переменная. В программировании весьма желательно давать всему осмысленные имена. Так в данном случае функция названа «посчитатьЕду» в переводе на русский.

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

После двоеточия следует тело, содержащее инструкции, которые выполняются при вызове функции. Следует различать определение функции и ее вызов. В программном коде они не рядом и не вместе. Можно определить функцию, но ни разу ее не вызвать. Нельзя вызвать функцию, которая не была определена. Определив функцию, но ни разу не вызвав ее, вы никогда не выполните ее тела.

Вызов функции

Рассмотрим полную версию программы с функцией:

def countFood():
    a = int(input())
    b = int(input())
    print("Всего", a+b, "шт.")
 
print("Сколько бананов и ананасов для обезьян?")
countFood()
 
print("Сколько жуков и червей для ежей?")
countFood()
 
print("Сколько рыб и моллюсков для выдр?")
countFood()

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

Когда функция вызывается, поток выполнения программы переходит к ее определению и начинает исполнять ее тело. После того, как тело функции исполнено, поток выполнения возвращается в основной код в то место, где функция вызывалась. Далее исполняется следующее за вызовом выражение.

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

print("Сколько бананов и ананасов для обезьян?")
countFood()
 
print("Сколько жуков и червей для ежей?")
countFood()
 
print("Сколько рыб и моллюсков для выдр?")
countFood()
 
def countFood():
    a = int(input())
    b = int(input())
    print("Всего", a+b, "шт.")

Результат:

Сколько бананов и ананасов для обезьян?
Traceback (most recent call last):
  File "test.py", line 2, in <module>
    countFood()
NameError: name 'countFood' is not defined

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

Функции придают программе структуру

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

Пусть надо написать программу, вычисляющую площади разных фигур. Пользователь указывает, площадь какой фигуры он хочет вычислить. После этого вводит исходные данные. Например, длину и ширину в случае прямоугольника. Чтобы разделить поток выполнения на несколько ветвей, следует использовать оператор if-elif-else:

figure = input("1-прямоугольник, 
2-треугольник, 3-круг: ")
 
if figure == '1':
  a = float(input("Ширина: "))
  b = float(input("Высота: "))
  print("Площадь: %.2f" % (a*b))
elif figure == '2':
  a = float(input("Основание: "))
  h = float(input("Высота: "))
  print("Площадь: %.2f" % (0.5 * a * h))
elif figure == '3':
  r = float(input("Радиус: "))
  print("Площадь: %.2f" % (3.14 * r**2))
else:
  print("Ошибка ввода")

Здесь нет никаких функций, и все прекрасно. Но напишем вариант с функциями:

def rectangle():
    a = float(input("Ширина: "))
    b = float(input("Высота: "))
    print("Площадь: %.2f" % (a*b))
 
def triangle():
    a = float(input("Основание: "))
    h = float(input("Высота: "))
    print("Площадь: %.2f" % (0.5 * a * h))
 
def circle():
    r = float(input("Радиус: "))
    print("Площадь: %.2f" % (3.14 * r**2))
 
figure = input("1-прямоугольник, 
2-треугольник, 3-круг: ")
if figure == '1':
  rectangle()
elif figure == '2':
  triangle()
elif figure == '3':
  circle()
else:
  print("Ошибка ввода")

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

Если нам когда-нибудь захочется вычислять площадь треугольника по формуле Герона, а не через высоту, то не придется искать код во всей программе (представьте, что она состоит из тысяч строк кода как реальные программы). Мы пойдем к месту определения функций и изменим тело одной из них.

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

Практическая работа

В программировании можно из одной функции вызывать другую. Для иллюстрации этой возможности напишите программу по следующему описанию.

Основная ветка программы, не считая заголовков функций, состоит из одной строки кода. Это вызов функции test(). В ней запрашивается на ввод целое число. Если оно положительное, то вызывается функция positive(), тело которой содержит команду вывода на экран слова «Положительное». Если число отрицательное, то вызывается функция negative(), ее тело содержит выражение вывода на экран слова «Отрицательное».

Понятно, что вызов test() должен следовать после определения функций. Однако имеет ли значение порядок определения самих функций? То есть должны ли определения positive() и negative() предшествовать test() или могут следовать после него? Проверьте вашу гипотезу, поменяв объявления функций местами. Попробуйте объяснить результат.

Примеры решения и дополнительные уроки в android-приложении и pdf-версии курса

Как определять функции в Python 3

В Python есть известные для многих функции:

  • функция Python print() выводит объект на печать в терминале;
  • int() превращает данные в целое число;
  • len() возвращает длину объекта.

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

Начнем с превращения в функцию классический «Hello, World!». Создадим в текстовом редакторе новый файл и назовем его hello.py. Затем определим функцию.

Функция определяется с помощью ключевого слова def, за которым следует название и параметры функции в круглых скобках (могут быть пустыми). Строку заканчиваем двоеточием.

В нашем случае определяем функцию с названием hello():

Мы создали начальную инструкцию для создания функции Python 3.

Теперь добавляем вторую строку, в которой устанавливаем инструкции для функции. В примере мы будем печатать в консоли «Hello, World»!

hello.py
def hello():
    print("Hello, World!")

Теперь строковая функция Python полностью определена, но если мы запустим программу, ничего не произойдет, так как мы не вызвали ее. Поэтому вызовем функцию с помощью hello():

hello.py
def hello():
    print("Hello, World!")

hello()

Запускаем программу:

Должно получиться следующее:

Результат

Hello, World!

Функции могут быть и сложнее, чем hello(). В блоке функции Python 3 можно использовать циклы for, условные инструкции и другое.

Например, следующая функция использует условную инструкцию для проверки того, содержит ли значение переменной name гласную, а затем применяет цикл for для итерации по буквам.

names.py

# Определяем функцию names()
def names():
    # Задаем имя переменной с вводом
    name = str(input('Введите имя: '))
    # Проверить, содержит ли имя гласную
    if set('aeiou').intersection(name.lower()):
        print('Имя содержит гласную.')
    else:
        print('Имя не содержит гласную.')

    # Итерация по имени
    for letter in name:
        print(letter)

# Вызываем функцию
names()

Вызов функции Python names(), которую мы определили, задает условную инструкцию и цикл for. Из этого примера видно, как можно организовать код в пределах функции. Также можно определить условное выражение и цикл for как две отдельные функции.

До сих пор мы рассматривали функции без аргументов. Но в скобках можно определять параметры для функций.
Параметр — это переменная в определении функции, указывающая аргумент, который функция должна принять.

Создадим небольшую программу с параметрами x, y и z. Определим функцию, которая суммирует параметры в различных конфигурациях. Она возвращает их сумму. Затем мы вызовем функцию и передадим в нее числа.

add_numbers.py
def add_numbers(x, y, z):
    a = x + y
    b = x + z
    c = y + z
    print(a, b, c)

add_numbers(1, 2, 3)

Мы передали число 1 в параметр x, число 2 в параметр y, и число 3 в параметр z. Эти значения соответствуют каждому параметру в том порядке, в котором они приведены.

Программа выполняет математические вычисления на основе значений параметров:

a = 1 + 2
b = 1 + 3
c = 2 + 3

Функция Python 3 выводит результаты математических расчетов a, b, и c, где a должно равняться 3, b — 4 и c — 5. Запускаем программу:

python add_numbers.py

Результат
3 4 5

Когда значения 1, 2 и 3 мы передаем в качестве параметров функции add_numbers(), то получаем ожидаемый результат.

Параметры — это аргументы, которые выступают в качестве переменных в определениях функций. Им можно задать значения при запуске метода для передачи аргументов в функцию.

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

Применяя именные аргументы, параметры можно задействовать не по порядку, потому что интерпретатор Python будет использовать ключевые слова, соответствующие значениям параметров.

Создадим Python математическую функцию, которая будет отображать информацию о профиле пользователя. Передадим параметры в функцию в виде username (строка) и followers (число).

profile.py
# Определяем функцию с параметрами
def profile_info(username, followers):
    print("Имя Username: " + username)
    print("Followers: " + str(followers))

В определении функции username и followers находятся в скобках. Блок функции выводит информацию о пользователе в виде строк с применением двух параметров.

Теперь можем вызвать функцию и назначить ей параметры:

profile.py
def profile_info(username, followers):
    print("Имя Username: " + username)
    print("Followers: " + str(followers))

# Вызываем функцию с указанными выше параметрами
profile_info("sammyshark", 945)

# Вызываем функцию с именованными аргументами
profile_info(username="AlexAnglerfish", followers=342)

При первом вызове функции Python мы ввели имя пользователя sammyshark и его 945 подписчиков. При втором вызове функции мы использовали именованные аргументы, присваивая значения переменным аргументов.

Запускаем программу:

python profile.py

Результат
Username: sammyshark
Followers: 945
Username: AlexAnglerfish
Followers: 342

В результате получаем имена пользователей и количество их подписчиков.

Из следующего примера видим, что для той же программы, но с другим вызовом, можно менять последовательность параметров:

profile.py
def profile_info(username, followers):
    print("Имя Username: " + username)
    print("Followers: " + str(followers))

# Изменяем последовательность параметров
profile_info(followers=820, username="cameron-catfish")

Снова запустив программу, получаем следующее:
Результат
Username: cameron-catfish
Followers: 820

При использовании именованных  аргументов функции Python последовательность их передачи при вызове функции не имеет значения.

Также можно указать значения по умолчанию для обоих параметров. Создадим значение по умолчанию для параметра followers со значением 1:

profile.py
def profile_info(username, followers=1):
    print("Имя Username: " + username)
    print("Followers: " + str(followers))

Теперь можно запустить функцию с параметром username, а число подписчиков по умолчанию будет 1. При желании можно изменить количество пользователей:

profile.py
def profile_info(username, followers=1):
    print("Имя Username: " + username)
    print("Followers: " + str(followers))

profile_info(username="JOctopus")
profile_info(username="sammyshark", followers=945)

Запустив программу командой python profile.py, получаем следующее:

Результат

Username: JOctopus
Followers: 1
Username: sammyshark
Followers: 945

Определяя начальные параметры, не нужно устанавливать значения для каждого аргумента.

Можно передавать значение аргумента функции в Python. При этом функция также может возвращать значение с помощью инструкции return, которая завершит выполнение функции и передаст значения к месту ее вызова. Используя return без аргументов, функция будет возвращать None.

До сих пор мы использовали print(), а не return. Создадим программу, которая вместо вывода в терминал будет возвращать переменную.

В новом текстовом файле создадим программу, которая будет возводить в квадрат параметр x и возвращать переменную y. Выполняем вызов, чтобы вывести переменную result после запуска функции square() с аргументом 3:

square.py
def square(x):
    y = x ** 2
    return y

result = square(3)
print(result)

Запускаем программу, чтобы увидеть результат:

python square.py

Результат
9

В качестве выходных данных получаем число 9, что и является результатом возведения в квадрат числа 3. Рассмотрим действие инструкции return в программе:

square.py
def square(x):
    y = x ** 2
    # return y

result = square(3)
print(result)

Снова запускаем программу:

python square.py

Результат
None

Без return программа не может вернуть значение, поэтому оно равно None.

В следующем примере математической функции в Python заменим print() из программы add_numbers.py на инструкцию return:

add_numbers.py
def add_numbers(x, y, z):
    a = x + y
    b = x + z
    c = y + z
    return a, b, c

sums = add_numbers(1, 2, 3)
print(sums)

Вне функции объявляем переменную sums, которая равна результату действия функции для чисел 1, 2 и 3 из примера, приведенного выше. Затем выводим переменную sums. Снова запускаем программу, теперь уже с инструкцией return:

python add_numbers.py

Результат

(3, 4, 5)

На выходе получаем те же числа, что и с использованием инструкции print(). Теперь результат предоставлен в виде кортежа, так как в списке выражений инструкции return имеется запятая.

Функции Python немедленно завершаются, когда встречают инструкцию return, независимо от того, возвращают они значение или нет:

return_loop.py
def loop_five():
    for x in range(0, 25):
        print(x)
        if x == 5:
            # Функция останавливается на x == 5
            return
    print("Эта строка не будет выполняться.")

loop_five()

Инструкция return в цикле for завершает функцию, поэтому строка вне цикла не будет выполняться. При использовании инструкции break был бы завершен только цикл, и выполнялась последняя строка print().

Инструкция return завершает функцию и может возвращать значение в случае применения параметров.

Хотя в Python можно вызывать функцию, которая находится в конце программы, во многих языках программирования (таких как C++ и Java) для выполнения программы требуется функция main. Применение функции main() не обязательно, но поможет организовать логику программы, помещая важные элементы в одну функцию.

Начнем с добавления Python функции main() в уже составленную программу hello.py. Оставляем функцию hello() и определяем функцию main():

hello.py
def hello():
    print("Hello, World!")

def main():

Применяем инструкцию print(), чтобы знать, что мы находимся в функции main(). Кроме этого вызовем функцию hello() внутри функции main():

hello.py
def hello():
    print("Hello, World!")

def main():
    print("Это главная функция")
    hello()

Ниже вызываем функцию main():

hello.py
def hello():
    print("Hello, World!")

def main():
    print("Это главная функция.")
    hello()

main()

Теперь запускаем программу:

python hello.py

Получаем следующее:
Результат
Это главная функция.
Hello, World!

Поскольку мы вызвали Python строковую функцию hello() внутри main(), а затем вызвали только функцию main(), то получили текст «Hello, World!» один раз после строки, которая сообщает, что мы находимся в главной функции.

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

На языке Python ‘__main__’ — это имя области, в которой будет выполняться код верхнего уровня. Если программа запускается стандартным вводом или с помощью интерактивного запроса, то __name__ устанавливается равным ‘__main__’.

В связи с этим существует соглашение о применении следующей конструкции:

if __name__ == '__main__':

    # Код для выполнения, когда это главная программа

Так мы получаем возможность использовать программные файлы в качестве:

  • главной программы и запускать ту часть, которая следует после инструкции if;
  • модуля и не запускать то, что следует после инструкции if.

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

Расширим программу names.py и создадим новый файл more_names.py. Объявим в этой программе глобальную переменную и изменим функцию names() так, чтобы инструкции находились в двух отдельных Python функциях.

Первая функция has_vowel() будет проверять, содержит ли строка name гласную. Вторая функция print_letters() выведет все буквы строки name:

more_names.py
# Объявляем глобальную переменную name для применения во всех функциях
name = str(input('Введите имя: '))

# Определяем функцию, чтобы проверить, содержит ли имя гласную букву
def has_vowel():
    if set('aeiou').intersection(name.lower()):
        print('Имя содержит гласную.')
    else:
        print('Имя не содержит гласную.')

# Итерация по буквам в строке имени
def print_letters():
    for letter in name:
        print(letter)

Определим main(), которая содержит вызов Python математических функций has_vowel() и print_letters():

more_names.py
# Объявить имя глобальной переменной для применения во всех функциях
name = str(input('Введите имя: '))

# Определяем функцию, чтобы проверить, содержит ли имя гласную букву
def has_vowel():
    if set('aeiou').intersection(name.lower()):
        print('Имя содержит гласную.')
    else:
        print('Имя не содержит гласную.')

# Итерация по буквам в строке имени
def print_letters():
    for letter in name:
        print(letter)

# Определяем основной метод для вызова других функций
def main():
    has_vowel()
    print_letters()

В конце файла добавляем конструкцию if __name__ == ‘__main__’:. Для запуска всех Python функций вызываем main() после инструкции if.

more_names.py

# Объявляем глобальную переменную name для применения во всех функциях
name = str(input('Введите имя: '))

# Определяем функцию, чтобы проверить, содержит ли имя гласную букву
def has_vowel():
    if set('aeiou').intersection(name.lower()):
        print('Имя содержит гласную.')
    else:
        print('Имя не содержит гласную.')

# Итерация по буквам в строке имени
def print_letters():
    for letter in name:
        print(letter)

# Определяем основной метод для вызова других функций
def main():
    has_vowel()
    print_letters()

# Выполняем функцию main()
if __name__ == '__main__':
    main()

Запускаем программу:

Программа генерирует тот же результат, что и программа names.py, но код в ней лучше организован, и его можно использовать в виде модуля без изменений.

Если не хотите объявлять Python функцию main(), то можете закончить программу так:

more_names.py
...
if __name__ == '__main__':
    has_vowel()
    print_letters()

Применение main() в качестве функции в сочетании с инструкцией if __name__ == ‘__main__’: поможет организовать код в логическом порядке, сделать его модульным и удобным для чтения.

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

Пожалуйста, оставьте ваши комментарии по текущей теме материала. За комментарии, лайки, отклики, дизлайки, подписки огромное вам спасибо!

Данная публикация является переводом статьи «How To Define Functions in Python 3» , подготовленная редакцией проекта.

4. Дополнительные инструменты управления потоком — документация Python 3.9.6

Помимо только что представленных операторов и , Python использует обычный
операторы управления потоком, известные из других языков, с некоторыми особенностями.

4.1.

if Выписки

Возможно, наиболее известным типом операторов является оператор if . Для
пример:

 >>> x = int (input ("Пожалуйста, введите целое число:"))
Введите целое число: 42
>>> если x <0:
... x = 0
... print ('Отрицательное значение изменено на ноль')
... elif x == 0:
... print ('Ноль')
... elif x == 1:
... print ('Одинокий')
... еще:
... print ('Подробнее')
...
Более
 

Может быть ноль или более частей elif , а часть else является
по желанию. Ключевое слово « elif » является сокращением от «else if» и полезно.
чтобы избежать чрезмерного вдавливания. , если elif
elif … последовательность заменяет переключатель или
case операторов на других языках.

4.2.

за Выписки

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

 >>> # Измерьте несколько строк:
... words = ['кошка', 'окно', 'defenestrate']
>>> вместо w прописью:
... print (w, len (w))
...
кошка 3
окно 6
дефенестрат 12
 

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

 # Стратегия: итерация по копии
для пользователя статус в users.copy (). items ():
    если статус == 'неактивен':
        del users [пользователь]

# Стратегия: Создать новую коллекцию
active_users = {}
для пользователя статус в пользователях.Предметы():
    если status == 'active':
        active_users [пользователь] = статус
 

4.3. Диапазон

() Функция

Если вам нужно перебрать последовательность чисел, встроенная функция
range () пригодится. Он генерирует арифметические прогрессии:

 >>> для i в диапазоне (5):
... печать (я)
...
0
1
2
3
4
 

Данная конечная точка никогда не является частью сгенерированной последовательности; диапазон (10) генерирует
10 значений, правовые индексы для элементов последовательности длиной 10.Это
можно позволить диапазону начинаться с другого числа или указать другое
приращение (даже отрицательное; иногда это называется «шагом»):

 >>> список (диапазон (5, 10))
[5, 6, 7, 8, 9]

>>> список (диапазон (0, 10, 3))
[0, 3, 6, 9]

>>> список (диапазон (-10, -100, -30))
[-10, -40, -70]
 

Для перебора индексов последовательности можно объединить range () и
len () следующим образом:

 >>> a = ['Мария', 'была', 'а', 'маленькая', 'барашка']
>>> для i в диапазоне (len (a)):
... print (i, a [i])
...
0 Мэри
1 имел
2 а
3 маленьких
4 баранины
 

В большинстве таких случаев, однако, удобно использовать enumerate ()
функции, см. Методы зацикливания.

Странная вещь происходит, если вы просто печатаете диапазон:

 >>> диапазон (10)
диапазон (0, 10)
 

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

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

 >>> сумма (диапазон (4)) # 0 + 1 + 2 + 3
6
 

Позже мы увидим больше функций, которые возвращают итерации и принимают итерации как
аргументы.В главе «Структуры данных» мы более подробно обсудим
список () .

4.4.

break и продолжить предложений и else пунктов в циклах

Оператор break , как и в C, выходит за пределы самого внутреннего окружающего
для или , а цикл .

Операторы цикла могут иметь предложение else ; он выполняется, когда цикл
завершается из-за исчерпания итерации (с для ) или когда
условие становится ложным (с и ), но не когда цикл
завершается оператором break .Примером может служить
следующий цикл, который ищет простые числа:

 >>> для n в диапазоне (2, 10):
... для x в диапазоне (2, n):
... если n% x == 0:
... print (n, 'равно', x, '*', n // x)
...             перерыв
...     еще:
... # цикл провалился, фактор не найден
... print (n, 'простое число')
...
2 - простое число
3 - простое число
4 равно 2 * 2
5 - простое число
6 равно 2 * 3
7 - простое число
8 равно 2 * 4
9 равно 3 * 3
 

(Да, это правильный код.Присмотритесь: пункт else принадлежит
для цикла , не для , если оператор .)

При использовании с циклом предложение else имеет больше общего с предложением
else в операторе try , чем в предложении
if : выполняется предложение try , предложение else
когда не возникает исключения, и условие цикла else выполняется, когда нет разрыва
имеет место.Для получения дополнительной информации об операторе try и исключениях см.
Обработка исключений.

Оператор continue , также заимствованный из C, продолжается следующим
итерация цикла:

 >>> для числа в диапазоне (2, 10):
... если число% 2 == 0:
... print ("Найдено четное число", num)
...         Продолжать
... print ("Найдено нечетное число", число)
...
Нашел четное число 2
Нашли нечетное число 3
Нашли четное число 4
Нашли нечетное число 5
Нашли четное число 6
Нашли нечетное число 7
Нашли четное число 8
Нашли нечетное число 9
 

4.5.

проездной Выписки

Оператор pass ничего не делает. Его можно использовать, когда оператор
требуется синтаксически, но программа не требует никаких действий. Например:

 >>> пока True:
... pass # Ожидание прерывания клавиатуры (Ctrl + C)
...
 

Обычно используется для создания минимальных классов:

 >>> класс MyEmptyClass:
...     проходить
...
 

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

 >>> def initlog (* args):
... pass # Не забудьте реализовать это!
...
 

4.6. Определение функций

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

 >>> def fib (n): # записываем ряд Фибоначчи до n
... "" "Выведите ряд Фибоначчи до n." ""
... а, Ь = 0, 1
... пока a >> # Теперь вызовем функцию, которую мы только что определили:
... выдумка (2000)
0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597
 

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

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

Выполнение функции вводит новую таблицу символов, используемую для локального
переменные функции. Точнее, все присвоения переменных в
функция сохраняет значение в локальной таблице символов; тогда как ссылки на переменные
сначала посмотрите в локальную таблицу символов, затем в локальные таблицы символов
включающие функции, затем в глобальную таблицу символов и, наконец, в таблицу
встроенных имен.Таким образом, глобальные переменные и переменные включающих функций
нельзя напрямую присвоить значение внутри функции (кроме случаев, когда глобальный
переменные, названные в глобальном операторе , или, для переменных включающих
функции, названные в нелокальном операторе ), хотя они могут
упоминается.

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

Определение функции связывает имя функции с объектом функции в
текущая таблица символов. Интерпретатор распознает объект, на который указывает
это имя как пользовательская функция. Другие имена также могут указывать на то же самое
объект функции, а также может использоваться для доступа к функции:

 >>> фиб
<функция fib at 10042ed0>
>>> f = фиб
>>> f (100)
0 1 1 2 3 5 8 13 21 34 55 89
 

Исходя из других языков, вы можете возразить, что fib не функция, а
процедура, поскольку она не возвращает значения.Фактически, даже функционирует без
return Оператор действительно возвращает значение, хотя и довольно утомительное. Этот
значение называется Нет (это встроенное имя). Запись значения Нет - это
обычно подавляется интерпретатором, если это единственное записанное значение.
Вы можете увидеть это, если действительно хотите использовать print () :

 >>> фиб (0)
>>> печать (фиб (0))
Никто
 

Очень просто написать функцию, которая возвращает список номеров
Ряд Фибоначчи, вместо того, чтобы печатать его:

 >>> def fib2 (n): # вернуть ряд Фибоначчи до n
... "" "Вернуть список, содержащий ряды Фибоначчи до n." ""
... результат = []
... а, Ь = 0, 1
... пока a >> f100 = fib2 (100) # вызовите это
>>> f100 # записываем результат
[0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]
 

Этот пример, как обычно, демонстрирует некоторые новые возможности Python:

  • Оператор return возвращает значение из функции. return без аргумента выражения возвращает None . Выпадать
    конец функции также возвращает Нет .

  • Оператор result.append (a) вызывает метод объекта списка
    результат . Метод - это функция, которая «принадлежит» объекту и называется
    obj.methodname , где obj - некоторый объект (это может быть выражение),
    и имя метода - имя метода, определяемого типом объекта.Разные типы определяют разные методы. Методы разных типов могут иметь
    одно и то же имя, не вызывая двусмысленности. (Можно определить свой собственный
    типы и методы объектов, использующие классов , см. Классы)
    Показанный в примере метод append () определен для объектов списка; Это
    добавляет новый элемент в конец списка. В этом примере это эквивалентно
    результат = результат + [a] , но более эффективно.

4,7. Подробнее об определении функций

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

4.7.1. Значения аргументов по умолчанию

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

 def ask_ok (подсказка, повторные попытки = 4, напоминание = 'Пожалуйста, попробуйте еще раз!'):
    в то время как True:
        ok = ввод (подсказка)
        если все в порядке ('y', 'ye', 'yes'):
            вернуть True
        если все в порядке в ('n', 'no', 'nop', 'nope'):
            вернуть ложь
        retries = retries - 1
        если повторных попыток <0:
            поднять ValueError ('недопустимый ответ пользователя')
        распечатать (напоминание)
 

Эту функцию можно вызвать несколькими способами:

  • с указанием только обязательного аргумента:
    ask_ok («Вы действительно хотите бросить?»)

  • с одним из необязательных аргументов:
    ask_ok ('Можно перезаписать файл?', 2)

  • или даже с указанием всех аргументов:
    ask_ok ('Можно перезаписать файл?', 2, 'Давай, только да или нет!')

В этом примере также вводится ключевое слово в .Это проверяет, действительно ли
не последовательность содержит определенное значение.

Значения по умолчанию оцениваются в точке определения функции в
, определяя область , так что

 я = 5

def f (arg = i):
    печать (аргумент)

я = 6
f ()
 

напечатает 5 .

Важное предупреждение: Значение по умолчанию оценивается только один раз. Это делает
разница, когда по умолчанию используется изменяемый объект, такой как список, словарь или
экземпляры большинства классов.Например, следующая функция накапливает
аргументы, переданные ему при последующих вызовах:

 def f (a, L = []):
    L.append (а)
    вернуть L

печать (f (1))
печать (f (2))
печать (f (3))
 

Будет напечатано

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

 def f (a, L = None):
    если L равно None:
        L = []
    L.append (а)
    вернуть L
 

4.7.2. Аргументы ключевого слова

Функции также можно вызывать с помощью аргументов ключевого слова
вида kwarg = значение .Например, следующая функция:

 def parrot (Voltage, state = 'a stiff', action = 'voom', type = 'Norwegian Blue'):
    print ("- Этот попугай не стал бы", action, end = '')
    print («если поставить», напряжение, «через это вольт».)
    print ("- Милое оперение,", тип)
    print ("- Это", состояние, "!")
 

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

 parrot (1000) # 1 позиционный аргумент
parrot (Voltage = 1000) # 1 аргумент ключевого слова
parrot (Voltage = 1000000, action = 'VOOOOOM') # 2 аргумента ключевого слова
parrot (action = 'VOOOOOM', Voltage = 1000000) # 2 аргумента ключевого слова
parrot ('миллион', 'лишенный жизни', 'прыжок') # 3 позиционные аргументы
parrot ('тысяча', state = 'поднимая ромашки') # 1 позиционный, 1 ключевое слово
 

, но все следующие вызовы будут недействительными:

 parrot () # отсутствует обязательный аргумент
попугай (напряжение = 5.0, 'dead') # аргумент без ключевого слова после аргумента ключевого слова
parrot (110, Voltage = 220) # повторяющееся значение для того же аргумента
попугай (актер = 'Джон Клиз') # неизвестный аргумент ключевого слова
 

При вызове функции аргументы ключевого слова должны следовать за позиционными аргументами.
Все переданные аргументы ключевого слова должны соответствовать одному из аргументов
принимается функцией (например, субъект не является допустимым аргументом для
parrot function), и их порядок не важен. Это также включает
необязательные аргументы (например,грамм. попугай (напряжение = 1000) тоже действительно).
Ни один аргумент не может принимать значение более одного раза.
Вот пример, который не работает из-за этого ограничения:

 >>> функция def (a):
...     проходить
...
>>> функция (0, a = 0)
Отслеживание (последний вызов последний):
  Файл "", строка 1, в 
TypeError: функция () получила несколько значений для аргумента ключевого слова 'a'
 

Когда присутствует последний формальный параметр формы ** имя , он получает
словарь (см. Типы сопоставления - dict), содержащий все аргументы ключевых слов, кроме
соответствующие формальному параметру.Это можно комбинировать с формальным
параметр формы * имя (описан в следующем подразделе), который
получает кортеж, содержащий позиционный
аргументы за пределами списка формальных параметров. ( * имя должно быть
перед ** имя .) Например, если мы определим такую ​​функцию:

 def cheeseshop (вид, * аргументы, ** ключевые слова):
    print ("- Есть ли у вас", добрый, "?")
    print ("- Извините, нас всех нет", любезно)
    для аргументов в аргументах:
        печать (аргумент)
    print ("-" * 40)
    для кВт в ключевых словах:
        print (квт, ":", ключевые слова [квт])
 

Его можно было назвать так:

 Cheeseshop («Лимбургер», «Очень жидкий, сэр.",
           "Это действительно очень, ОЧЕНЬ жидкий, сэр.",
           shopkeeper = "Майкл Пэйлин",
           client = "Джон Клиз",
           sketch = "Эскиз сырной лавки")
 

и, конечно, напечатает:

 - У вас есть лимбургер?
- Извините, у нас все кончились из Лимбургера
Он очень жидкий, сэр.
Он действительно очень, ОЧЕНЬ жидкий, сэр.
----------------------------------------
владелец магазина: Майкл Пэйлин
клиент: Джон Клиз
эскиз: Эскиз сырной лавки
 

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

4.7.3. Специальные параметры

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

Определение функции может выглядеть так:

 def f (pos1, pos2, /, pos_or_kwd, *, kwd1, kwd2):
      ----------- ---------- ----------
        | | |
        | Позиционное или ключевое слово |
        | - Только ключевое слово
         - Только позиционное
 

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

4.7.3.1. Аргументы позиционного или ключевого слова

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

4.7.3.2. Только позиционные параметры

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

Параметры, следующие за /, могут быть с позиционным или ключевым словом или с ключевым словом .

4.7.3.3. Аргументы только для ключевых слов

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

4.7.3.4. Примеры функций

Рассмотрим следующие примеры определений функций, уделяя пристальное внимание
маркеры / и * :

 >>> def standard_arg (аргумент):
... печать (аргумент)
...
>>> def pos_only_arg (аргумент, /):
... печать (аргумент)
...
>>> def kwd_only_arg (*, arg):
... печать (аргумент)
...
>>> def комбинированный_пример (pos_only, /, standard, *, kwd_only):
... print (pos_only, standard, kwd_only)
 

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

 >>> стандартный_арг (2)
2

>>> стандартный_арг (аргумент = 2)
2
 

Вторая функция pos_only_arg может использовать только позиционные
параметры, поскольку в определении функции есть /:

 >>> pos_only_arg (1)
1

>>> pos_only_arg (аргумент = 1)
Отслеживание (последний вызов последний):
  Файл "", строка 1, в 
TypeError: pos_only_arg () получил неожиданный аргумент ключевого слова 'arg'
 

Третья функция kwd_only_args допускает только указанные аргументы
на * в определении функции:

 >>> kwd_only_arg (3)
Отслеживание (последний вызов последний):
  Файл "", строка 1, в 
TypeError: kwd_only_arg () принимает 0 позиционных аргументов, но дан 1

>>> kwd_only_arg (arg = 3)
3
 

И последний использует все три соглашения о вызовах в одной функции.
определение:

 >>> комбинированный_пример (1, 2, 3)
Отслеживание (последний вызов последний):
  Файл "", строка 1, в 
TypeError: Combined_example () принимает 2 позиционных аргумента, но было дано 3

>>> комбинированный_пример (1, 2, kwd_only = 3)
1 2 3

>>> комбинированный_пример (1, стандартный = 2, kwd_only = 3)
1 2 3

>>> комбинированный_пример (pos_only = 1, standard = 2, kwd_only = 3)
Отслеживание (последний вызов последний):
  Файл "", строка 1, в 
TypeError: Combined_example () получил неожиданный аргумент ключевого слова 'pos_only'
 

Наконец, рассмотрим это определение функции, которое имеет потенциальную коллизию между позиционным аргументом name и ** kwds , который имеет name в качестве ключа:

 def foo (имя, ** kwds):
    вернуть 'name' в kwds
 

Нет возможного вызова, который заставил бы его вернуть True в качестве ключевого слова 'name'
всегда будет привязан к первому параметру.Например:

 >>> foo (1, ** {'имя': 2})
Отслеживание (последний вызов последний):
  Файл "", строка 1, в 
TypeError: foo () получил несколько значений для аргумента 'name'
>>>
 

Но используя / (только позиционные аргументы), это возможно, поскольку оно позволяет name в качестве позиционного аргумента и 'name' в качестве ключа в аргументах ключевого слова:

 def foo (имя, /, ** kwds):
    вернуть 'name' в kwds
>>> foo (1, ** {'имя': 2})
Правда
 

Другими словами, имена только позиционных параметров могут использоваться в
** kwds без двусмысленности.

4.7.3.5. Резюме

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

 def f (pos1, pos2, /, pos_or_kwd, *, kwd1, kwd2):
 

В качестве руководства:

  • Используйте только позиционный, если вы хотите, чтобы имя параметров не отображалось
    доступны пользователю. Это полезно, когда в именах параметров нет реальных
    это означает, что если вы хотите обеспечить соблюдение порядка аргументов, когда функция
    вызывается или если вам нужно взять какие-то позиционные параметры и произвольные
    ключевые слова.

  • Используйте только ключевые слова, если имена имеют значение, а определение функции
    более понятным, если указывать явные имена или вы хотите предотвратить
    пользователи, полагающиеся на позицию переданного аргумента.

  • Для API используйте только позиционное, чтобы предотвратить нарушение изменений API
    если имя параметра будет изменено в будущем.

4.7.4. Списки произвольных аргументов

Наконец, наименее часто используемый параметр - указать, что функция может быть
вызывается с произвольным количеством аргументов.Эти аргументы будут упакованы
вверх в кортеж (см. Кортежи и последовательности). Перед переменным количеством аргументов,
может появиться ноль или более нормальных аргументов.

 def write_multiple_items (файл, разделитель, * аргументы):
    file.write (separator.join (аргументы))
 

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

 >>> def concat (* args, sep = "/"):
... вернуть sep.join (args)
...
>>> concat («земля», «марс», «венера»)
'земля / марс / венера'
>>> concat ("земля", "марс", "венера", sep = ".")
'earth.mars.venus'
 

4.7.5. Распаковка списков аргументов

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

 >>> list (range (3, 6)) # нормальный вызов с отдельными аргументами
[3, 4, 5]
>>> args = [3, 6]
>>> list (range (* args)) # вызов с аргументами, распакованными из списка
[3, 4, 5]
 

Таким же образом словари могут доставлять аргументы ключевых слов с
** -оператор:

 >>> def parrot (Voltage, state = 'a stiff', action = 'voom'):
... print ("- Этот попугай не стал бы", action, end = '')
... print ("если поставить", напряжение, "через него вольт.", end = '')
... print ("E", состояние "!")
...
>>> d = {"Voltage": "четыре миллиона", "state": "bleedin 'demised", "action": "VOOM"}
>>> попугай (** d)
- Этот попугай не загудит, если вы пропустите через него четыре миллиона вольт. Е истекает кровью!
 

4.7.6. Лямбда-выражения

Небольшие анонимные функции могут быть созданы с помощью ключевого слова lambda .Эта функция возвращает сумму двух своих аргументов: лямбда a, b: a + b .
Лямбда-функции можно использовать везде, где требуются функциональные объекты. Они есть
синтаксически ограничен одним выражением. Семантически они просто
синтаксический сахар для определения нормальной функции. Как вложенная функция
определения, лямбда-функции могут ссылаться на переменные из содержащих
объем:

 >>> def make_incrementor (n):
... вернуть лямбда x: x + n
...
>>> f = make_incrementor (42)
>>> f (0)
42
>>> f (1)
43 год
 

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

 >>> пары = [(1, 'один'), (2, 'два'), (3, 'три'), (4, 'четыре')]
>>> pair.sort (ключ = лямбда-пара: пара [1])
>>> пары
[(4, 'четыре'), (1, 'один'), (3, 'три'), (2, 'два')]
 

4.7.7. Строки документации

Вот некоторые соглашения о содержании и форматировании документации.
струны.

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

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

Синтаксический анализатор Python не удаляет отступы из многострочных строковых литералов в
Python, поэтому инструменты, обрабатывающие документацию, должны удалять отступы, если
желанный. Это делается по следующему соглашению. Первая непустая строка
после первая строка строки определяет величину отступа для
вся строка документации. (Мы не можем использовать первую строку, так как она
обычно рядом с открывающими кавычками строки, поэтому отступ не
очевидно в строковом литерале.) Пробел, «эквивалентный» этому отступу:
затем удаляются с начала всех строк строки. Линии, которые
с меньшим отступом не должно быть, но если они встречаются, все их ведущие пробелы
следует раздеть. Эквивалентность пробелов следует проверить после раскрытия.
вкладок (до 8 пробелов, обычно).

Вот пример многострочной строки документации:

 >>> def my_function ():
... "" "Ничего не делайте, но задокументируйте.
...
... Нет, правда, ничего не делает.... "" "
...     проходить
...
>>> print (my_function .__ doc__)
Ничего не делайте, но задокументируйте.

    Нет, правда, ничего не делает.
 

4.7.8. Аннотации функций

Аннотации функций - это полностью необязательные метаданные
информацию о типах, используемых определяемыми пользователем функциями (см. PEP 3107, и
PEP 484 для получения дополнительной информации).

Аннотации хранятся в __annotations__
атрибут функции как словаря и не влияет ни на какие другие части
функция.Аннотации параметров определяются двоеточием после имени параметра, за которым следует
выражением, оценивающим значение аннотации. Возвратные аннотации
определяется литералом -> , за которым следует выражение между параметром
list и двоеточие, обозначающее конец оператора def . В
в следующем примере есть обязательный аргумент, необязательный аргумент и возвращаемый
аннотированное значение:

 >>> def f (ветчина: str, яйца: str = 'яйца') -> str:
... print ("Аннотации:", f .__ annotations__)
... print ("Аргументы:", ветчина, яйца)
... вернуть ветчину + 'и' + яйца
...
>>> f ('спам')
Аннотации: {'ветчина': <класс 'str'>, 'return': <класс 'str'>, 'яйца': <класс 'str'>}
Аргументы: спам-яйца
"спам и яйца"
 

4.8. Интермеццо: стиль кодирования

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

Для Python PEP 8 стал руководством по стилю, которого придерживается большинство проектов;
он способствует очень удобочитаемому и приятному для глаз стилю кодирования. Каждый Python
разработчик должен прочитать это в какой-то момент; вот самые важные моменты
извлечено для вас:

  • Используйте отступ из 4 пробелов, без табуляции.

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

  • Переносить строки так, чтобы они не превышали 79 символов.

    Это помогает пользователям с небольшими дисплеями и позволяет иметь несколько
    файлы кода бок о бок на больших дисплеях.

  • Используйте пустые строки для разделения функций и классов, а также большие блоки
    код внутри функций.

  • По возможности помещайте комментарии в отдельной строке.

  • Используйте строки документации.

  • Используйте пробелы вокруг операторов и после запятых, но не непосредственно внутри
    конструкции в скобках: a = f (1, 2) + g (3, 4) .

  • Называйте классы и функции последовательно; соглашение заключается в использовании
    UpperCamelCase для классов и lowercase_with_underscores для функций
    и методы. Всегда используйте self как имя для первого аргумента метода
    (дополнительные сведения о классах и методах см. в разделе «Первый взгляд на классы»).

  • Не используйте причудливые кодировки, если ваш код предназначен для использования в международных
    среды. Стандарт Python, UTF-8 или даже простой ASCII лучше всего работает в любом
    дело.

  • Точно так же не используйте символы, отличные от ASCII, в идентификаторах, если есть только
    малейший шанс, что люди, говорящие на другом языке, будут читать или поддерживать
    код.

Сноски

Встроенные функции

- документация Python 3.9.6

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

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

режим - необязательная строка, указывающая режим, в котором файл
открыт. По умолчанию это 'r' , что означает открытие для чтения в текстовом режиме.
Другие общие значения: 'w' для записи (усечение файла, если он
уже существует), 'x' для эксклюзивного создания и 'a' для добавления
(что в некоторых системах Unix означает, что все записи добавляются в конец
файл независимо от текущей позиции поиска).В текстовом режиме, если
Кодировка не указана, используемая кодировка зависит от платформы:
locale.getpreferredencoding (False) вызывается для получения текущей локали
кодирование. (Для чтения и записи сырых байтов используйте двоичный режим и оставьте
кодировка не указана.) Доступные режимы:

Знак

Значение

'r'

открыто для чтения (по умолчанию)

'ширина'

открыт для записи, сначала обрезка файла

'x'

открыто для монопольного создания, ошибка, если файл уже существует

'а'

открыто для записи, добавляется в конец файла, если он существует

'b'

двоичный режим

'т'

текстовый режим (по умолчанию)

'+'

открыт для обновления (чтение и запись)

Режим по умолчанию - 'r' (открыт для чтения текста, синоним 'rt' ).Режимы 'w +' и 'w + b' открывают и обрезают файл. Режимы 'r +'
и 'r + b' открывают файл без усечения.

Как упоминалось в обзоре, Python различает двоичные
и текстовый ввод / вывод. Файлы, открытые в двоичном режиме (включая 'b' в режиме
аргумент) возвращает содержимое как байта объектов без какого-либо декодирования. В
текстовый режим (по умолчанию или когда 't' включено в аргумент mode ),
содержимое файла возвращается как str , байты были
сначала декодируется с использованием платформенно-зависимого кодирования или с использованием указанного
кодирование , если указано.

Разрешен дополнительный символ режима, 'U' , который больше не
имеет какой-либо эффект и считается устаревшим. Ранее он был включен
универсальные символы новой строки в текстовом режиме, которые стали поведением по умолчанию
в Python 3.0. См. Документацию к
параметр новой строки для получения дополнительных сведений.

Примечание

Python не зависит от представления текста операционной системой.
файлы; вся обработка выполняется самим Python и, следовательно,
независимая платформа.

буферизация - необязательное целое число, используемое для установки политики буферизации. Пройти 0
для выключения буферизации (разрешено только в двоичном режиме), 1 для выбора строки
буферизация (может использоваться только в текстовом режиме) и целое число> 1, чтобы указать размер
в байтах буфера фрагментов фиксированного размера. Когда нет буферизации аргумент
Учитывая, что политика буферизации по умолчанию работает следующим образом:

  • Двоичные файлы буферизуются фрагментами фиксированного размера; размер буфера
    выбирается с помощью эвристики, пытающейся определить «блокировку» основного устройства
    размер »и возвращается к io.DEFAULT_BUFFER_SIZE . Во многих системах
    размер буфера обычно составляет 4096 или 8192 байта.

  • «Интерактивные» текстовые файлы (файлы, для которых isatty ()
    возвращает True ) использовать буферизацию строки. Другие текстовые файлы используют политику
    описано выше для двоичных файлов.

кодировка - это имя кодировки, используемой для декодирования или кодирования файла.
Это следует использовать только в текстовом режиме. Кодировка по умолчанию - платформа.
зависимый (независимо от локали .getpreferredencoding () возвращает), но любой
кодировка текста, поддерживаемая Python
может быть использован. См. Модуль кодеков для
список поддерживаемых кодировок.

ошибки - дополнительная строка, указывающая способ кодирования и декодирования.
ошибки должны обрабатываться - это не может использоваться в двоичном режиме.
Доступны различные стандартные обработчики ошибок.
(перечислены в разделе «Обработчики ошибок»), хотя любые
имя обработки ошибок, которое было зарегистрировано с
codecs.register_error () также допустим.Стандартные имена
включают:

  • 'strict' , чтобы вызвать исключение ValueError , если есть
    ошибка кодировки. Значение по умолчанию Нет имеет то же самое
    эффект.

  • 'ignore' игнорирует ошибки. Обратите внимание, что игнорирование ошибок кодирования
    может привести к потере данных.

  • 'replace' вызывает вставку маркера замены (например, '?' )
    где есть искаженные данные.

  • 'surrogateescape' будет представлять любые неправильные байты как код
    точек в области частного использования Unicode в диапазоне от U + DC80 до
    U + DCFF.Эти частные кодовые точки будут затем снова превращены в
    те же байты при использовании обработчика ошибок surrogateescape
    при записи данных. Это полезно для обработки файлов в
    неизвестная кодировка.

  • 'xmlcharrefreplace' поддерживается только при записи в файл.
    Символы, не поддерживаемые кодировкой, заменяются символами
    ссылка на соответствующий символ XML & # nnn; .

  • 'backslashreplace' заменяет искаженные данные на обратную косую черту Python
    escape-последовательности.

  • 'namereplace' (также поддерживается только при записи)
    заменяет неподдерживаемые символы на \ N {...} управляющих последовательностей.

новая строка управляет тем, как работает универсальный режим новой строки (только
относится к текстовому режиму). Это может быть Нет , ', ' \ n ', ' \ r ' и
'\ r \ n' . Работает следующим образом:

  • При чтении ввода из потока, если перевод строки равен Нет , универсальный
    Режим новой строки включен.Строки на входе могут заканчиваться на '\ n' ,
    '\ r' или '\ r \ n' , и они переводятся в '\ n' перед
    возвращаются вызывающему абоненту. Если это '' , универсальный режим новой строки
    включен, но окончания строк возвращаются вызывающему абоненту без перевода. Если это
    имеет любое из других допустимых значений, строки ввода заканчиваются только
    заданная строка, и конец строки возвращается вызывающему абоненту без перевода.

  • При записи вывода в поток, если перевод строки равен Нет , любой '\ n'
    написанные символы переводятся в системный разделитель строк по умолчанию,
    ос.linesep . Если новая строка - это '' или '\ n' , перевода нет
    происходит. Если новая строка - любое другое допустимое значение, любое '\ n'
    написанные символы переводятся в заданную строку.

Если closefd - Ложь и был указан дескриптор файла, а не имя файла.
задано, базовый дескриптор файла будет оставаться открытым, когда файл
закрыто. Если указано имя файла closefd должно быть True (по умолчанию)
в противном случае возникнет ошибка.

Можно использовать настраиваемый открыватель, передав вызываемый объект как открыватель . Лежащий в основе
файловый дескриптор для файлового объекта затем получается путем вызова средства открытия с
( файл , флаги ). открыватель должен возвращать дескриптор открытого файла (передавая
os.open as opener приводит к функциональности, аналогичной прохождению
Нет ).

Вновь созданный файл не наследуется.

В следующем примере используется параметр dir_fd
ос.open () , чтобы открыть файл, относящийся к заданному каталогу:

 >>> импорт ОС
>>> dir_fd = os.open ('somedir', os.O_RDONLY)
>>> def opener (путь, флаги):
... вернуть os.open (путь, флаги, dir_fd = dir_fd)
...
>>> с open ('spamspam.txt', 'w', opener = opener) как f:
... print ('Это будет записано в somedir / spamspam.txt', file = f)
...
>>> os.close (dir_fd) # не допускать утечки файлового дескриптора
 

Тип файлового объекта, возвращаемого функцией open () .
зависит от режима.Когда open () используется для открытия файла в тексте
mode ( 'w' , 'r' , 'wt' , 'rt' и т. д.), он возвращает подкласс
io.TextIOBase (а именно io.TextIOWrapper ). При использовании
чтобы открыть файл в двоичном режиме с буферизацией, возвращаемый класс -
подкласс io.BufferedIOBase . Точный класс варьируется: в прочтении
в двоичном режиме возвращается io.BufferedReader ; в записи двоичного кода и
добавить двоичные режимы, он возвращает io.BufferedWriter , а в
режим чтения / записи, он возвращает io.BufferedRandom . Когда буферизация
отключен, необработанный поток, подкласс io.RawIOBase ,
io.FileIO , возвращается.

См. Также модули обработки файлов, например, fileinput , io
(где объявлено open () ), os , os.path , tempfile ,
и шутил .

Вызывает событие аудита открыть с аргументами файл , режим , флаги .

Режим Флаги и аргументы могли быть изменены или выведены из
исходный звонок.

Изменено в версии 3.3:

  • Добавлен параметр opener .

  • Добавлен режим 'x' .

  • IOError раньше вызывался, теперь это псевдоним OSError .

  • FileExistsError теперь возникает, если файл открывается в монопольном режиме.
    режим создания ( 'x' ) уже существует.

Устарело с версии 3.4, будет удалено в версии 3.10: Режим 'U' .

Изменено в версии 3.5:

  • Если системный вызов прерывается и обработчик сигнала не вызывает
    исключение, функция теперь повторяет системный вызов вместо того, чтобы вызывать
    InterruptedError исключение (объяснение см. В PEP 475 ).

  • Добавлен обработчик ошибок namereplace .

Python 3 Примечания: Пользовательские функции

На этой странице: функции def, return, docstrings, help (), функции возврата значения и void

Функции: основы

Давайте откажемся от старой алгебры. Вы узнали «функции» как что-то вроде:
f (x) = x 2 + 1

В Python определение функции работает следующим образом. def - ключевое слово для определения функции. За именем функции следует параметр (ы) в ().Двоеточие: означает начало тела функции, которое отмечено отступом. Внутри тела функции оператор return определяет возвращаемое значение. После завершения определения функции вызов функции с аргументом возвращает значение.

>>> def f (x):
        возврат x ** 2 + 1

>>> f (4)
17
>>>
 

Попробуем другую функцию. Ниже приведена функция, которая принимает глагол (надеюсь) и возвращает герундийную форму:

>>> def get_ing (wd):
        вернуть wd + 'ing'

>>> get_ing ('прогулка')
'гулять пешком'
>>>
 

Несколько параметров, строка документации

Ниже представлена ​​чуть более сложная функция.Он принимает два аргумента, имеет условное выражение в теле функции и начинается со строки:

>>> def same_initial (wd1, wd2):
        "" "Проверяет, начинаются ли два слова с одного и того же символа,
        и возвращает True / False. Различие в регистре игнорируется.
        если wd1 [0] .lower () == wd2 [0] .lower ():
            вернуть True
        еще:
            вернуть ложь

>>> same_initial ('яблоко', 'апельсин')
Ложь
>>> same_initial ('Энни', 'яблоко')
Правда
>>>
 

"" "Проверяет, если... Строка "" "называется" docstring ". Размещенная в самом верху тела функции, она действует как документация для функции. Эта строка распечатывается, когда вы вызываете help () для функции:

>>> справка (same_initial)
Справка по функции same_initial в модуле __main__:

same_initial (wd1, wd2)
    Проверяет, начинаются ли два слова с одного и того же символа,
    и возвращает True / False. Различие в регистре игнорируется.
>>>
 

Вот еще один пример.Эта функция возвращает список символов, общих для двух строк. (Было бы лучше, если бы не было дубликатов. Можно улучшить?)

>>> def in_both (wd1, wd2):
        «Принимает две строки, возвращает отсортированный список общих символов»
        common = []
        для c в wd1:
            если c в wd2:
                common.append (c)
        вернуть отсортированный (обычный)

>>> in_both ('груша', 'яблоко')
['a', 'e', ​​'p']
>>> in_both ('лингвистика', 'экономика')
['c', 'i', 'i', 'i', 'n', 's', 's']
>>>
 

Функции: Возвращение vs.Пустота

Вы можете подумать: «Погодите минутку, я не видел никакого оператора возврата в учебнике по определению функций». Вы правы - определенная Эд функция get_legal () не включала никакого оператора возврата, а только набор функций печати.
В Python можно составить функцию без оператора возврата. Такие функции называются void , и они возвращают None, специальный объект Python "ничего". Вот пример функции void:

>>> def sayhello (кто):
        print ('Привет,', кто + '!')
        print ('Какой прекрасный день.')

>>> Sayhello ('Акбар')
Привет, Акбар!
Какой прекрасный день.
>>>
 

Хорошо, тогда чем отличаются функции void и функции типа "return"? Хороший вопрос. Позвольте мне проиллюстрировать это на примерах. Вот функция get_ing (), определенная выше, и ее недействительный аналог print_ing ():

>>> def get_ing (wd):
        вернуть wd + 'ing'

>>> def print_ing (wd):
        печать (wd + 'ing')

 

Вызывая две функции, вы сначала замечаете небольшую разницу в выводе.Возвращающая функция дает вам строку (примечание ''), а функция печати показывает напечатанный вывод строки - обратите внимание на отсутствие кавычек. Обратите внимание, что возвращаемое значение отображается только в интерактивной среде оболочки; в сценарии только команды печати приводят к отображению вывода.

>>> get_ing ('интерес')
'интересно'
>>> print_ing ('интерес')
интересно
>>>
 

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

>>> foo = get_ing ('интерес')
>>> фу
'интересно'
>>> faa = print_ing ('интерес')
интересно
>>> фаа
>>>
 

Кроме того, функцию, возвращающую значение, можно подключить прямо к другой функции.Опять же, поскольку функции void ничего не возвращают, они не могут. Ниже get_ing ('eat') передается в функцию len () для успешного результата. С помощью len (print_ing ('eat')) печать происходит независимо, а затем возникает ошибка типа:

>>> len (get_ing ('есть'))
6
>>> len (print_ing ('есть'))
принимать пищу

Отслеживание (последний вызов последний):
  Файл "", строка 1, в 
    len (print_ing ('есть'))
TypeError: объект типа NoneType не имеет len ()
 

Наконец, если вам нужна печать, ее также можно выполнить с помощью функции возврата значения: просто используйте с ней оператор печати.

>>> print (get_ing ('интерес'))
интересно
>>> print_ing ('интерес')
интересно
>>>
 

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

Функции Python


Функция - это блок кода, который выполняется только при вызове.

В функцию можно передавать данные, называемые параметрами.

В результате функция может возвращать данные.


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

В Python функция определяется с использованием def
ключевое слово:

Пример

def my_function ():
print («Привет от функции»)


Вызов функции

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

Пример

def my_function ():
print («Привет от функции»)

my_function ()

Попробуй сам "


Аргументы

Информация может передаваться в функции как аргументы.

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

В следующем примере есть функция с одним аргументом (fname).
Когда функция вызывается, мы передаем имя,
который используется внутри функции для вывода полного имени:

Пример

def my_function ( fname ):
print (fname + "Refsnes")

my_function ( "Emil" )
my_function ( "Tobias" )
my_function ( "Linus" )

Попробуй сам "

Аргументы часто сокращаются до аргументов в документации Python.



Параметры или аргументы?

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

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

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

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


Количество аргументов

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

Пример

Эта функция ожидает 2 аргумента и получает 2 аргумента:

def my_function (fname, lname):
print (fname + "" + lname)

my_function ("Emil", "Refsnes")

Попробуй сам "

Если вы попытаетесь вызвать функцию с 1 или 3 аргументами, вы получите ошибку:

Пример

Эта функция ожидает 2 аргумента, но получает только 1:

def my_function (fname, lname):
print (fname + "" + lname)

my_function ("Emil")

Попробуй сам "


Произвольные аргументы, * args

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

Таким образом, функция получит кортеж из , аргументов и сможет обращаться к элементам соответственно:

Пример

Если количество аргументов неизвестно, добавьте перед именем параметра * :

def my_function (* kids):
print («Самый младший ребенок
is "+ kids [2])

my_function (" Эмиль "," Тобиас "," Линус ")

Попробуй сам "

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


Аргументы ключевого слова

Вы также можете отправлять аргументы с синтаксисом ключ = значение .

Таким образом, порядок аргументов не имеет значения.

Пример

def my_function (child3, child2, child1):
print ("Самый младший ребенок
is "+ child3"

my_function (child1 = "Emil", child2 = "Tobias", child3 = "Linus")

Попробуй сам "

Фраза Аргументы ключевого слова часто сокращается до kwargs в документации Python.


Аргументы произвольного ключевого слова, ** kwargs

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

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

Пример

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

def my_function (** kid):
print ("Его фамилия" + kid ["lname"])

my_function (fname = "Tobias", lname = "Refsnes")

Попробуй сам "

Произвольные аргументы Kword часто сокращаются до ** kwargs в документации Python.


Значение параметра по умолчанию

В следующем примере показано, как использовать значение параметра по умолчанию.

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

Пример

def my_function ( country = "Норвегия" ):
print ("Я из" +
страна)

my_function («Швеция»)
my_function («Индия»)
my_function ()
my_function («Бразилия»)

Попробуй сам "


Передача списка в качестве аргумента

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

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

Пример

def my_function (food):
для x в food:
print (x)

fruit = ["яблоко", "банан", "вишня"]

my_function (fruit)

Попробуй сам "


Возвращаемые значения

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

Пример

def my_function (x):
return 5 * x

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

Попробуй сам "


Пропуск Заявление

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


Рекурсия

Python также принимает рекурсию функций, что означает, что определенная функция может вызывать сама себя.

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

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

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

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

Пример

Пример рекурсии

def tri_recursion (k):

если (k> 0):

результат = k + tri_recursion (k - 1)

print (результат)

еще:

результат = 0

вернуть результат

print ("\ n \ nRecursion Example Results")
tri_recursion (6)

Попробуй сам "



Определение функций в Python 3

Введение

Функция - это блок инструкций, который выполняет действие и, однажды определенный, может использоваться повторно.Функции делают код более модульным, позволяя использовать один и тот же код снова и снова.

Python имеет ряд встроенных функций, с которыми вы, возможно, знакомы, в том числе:

  • print () , который распечатает объект на терминал
  • int () , который преобразует строковый или числовой тип данных в целочисленный тип данных
  • len () , который возвращает длину объекта

Имена функций включают круглые скобки и могут включать параметры.

В этом руководстве мы рассмотрим, как определять собственные функции для использования в проектах кодирования.

Определение функции

Начнем с классического "Hello, World!" программу в функцию.

Мы создадим новый текстовый файл в выбранном текстовом редакторе и вызовем программу hello.py . Затем мы определим функцию.

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

В этом случае мы определим функцию с именем hello () :

hello.py

  def hello ():
  

Устанавливает начальную инструкцию для создания функции.

Отсюда мы добавим вторую строку с отступом из 4 пробелов, чтобы предоставить инструкции для того, что делает функция. В этом случае мы напечатаем Hello, World! на консоль:

hello.py

  def hello ():
    print ("Привет, мир!")

  

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

Итак, вне нашего определенного функционального блока, давайте вызовем функцию с hello () :

hello.py

  def hello ():
    print ("Привет, мир!")

Привет()

  

Теперь запустим программу:

  

Вы должны получить следующий результат:

  

Выход

Hello, World!

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

Например, функция, определенная ниже, использует условный оператор для проверки, содержит ли вход для переменной name гласную, а затем использует цикл for для перебора букв в строке name .

names.py

  # Определить имена функций ()
def names ():
    # Настроить имя переменной с вводом
    name = str (input ('Введите свое имя:'))
    # Проверить, есть ли в имени гласная
    если установлено ('aeiou'). пересечение (name.ниже()):
        print ('Ваше имя содержит гласную.')
    еще:
        print ('Ваше имя не содержит гласных.')

    # Итерировать по имени
    на букву в имени:
        печать (письмо)

# Вызов функции
имена ()

  

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

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

Работа с параметрами

До сих пор мы рассматривали функции с пустыми скобками, которые не принимают аргументов, но мы можем определять параметры в определениях функций в их скобках.

Параметр - это именованная сущность в определении функции, указывающая аргумент, который функция может принимать.

Давайте создадим небольшую программу, которая принимает параметры x , y и z . Мы создадим функцию, которая складывает параметры вместе в различных конфигурациях. Их суммы будут напечатаны функцией. Затем мы вызовем функцию и передадим ей числа.

add_numbers.py

  def add_numbers (x, y, z):
    а = х + у
    б = х + г
    с = у + г
    печать (a, b, c)

add_numbers (1, 2, 3)

  

Мы передали число 1 для параметра x , 2 для параметра y и 3 для параметра z .Эти значения соответствуют каждому параметру в том порядке, в котором они указаны.

Программа, по сути, выполняет следующую математику на основе значений, которые мы передали в параметры:

  а = 1 + 2
б = 1 + 3
с = 2 + 3
  

Функция также печатает a , b и c , и на основе приведенных выше математических расчетов мы ожидаем, что a будет равно 3 , b будет равно 4 и c будет 5 .Запустим программу:

  
  

Выход

3 4 5

Когда мы передаем 1 , 2 и 3 в качестве параметров функции add_numbers () , мы получаем ожидаемый результат.

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

Аргументы ключевого слова

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

Когда вы используете аргументы ключевого слова, вы можете использовать параметры не по порядку, потому что интерпретатор Python будет использовать предоставленные ключевые слова для сопоставления значений с параметрами.

Давайте создадим функцию, которая будет показывать нам информацию профиля пользователя. Мы передадим ему параметры в виде имени пользователя (в виде строки) и подписчиков (в виде целого числа).

profile.py

  # Определить функцию с параметрами
def profile_info (имя пользователя, подписчики):
    print ("Имя пользователя:" + имя пользователя)
    print ("Подписчики:" + str (подписчики))

  

В операторе определения функции имени пользователя и последователей содержатся в скобках функции profile_info () .Блок функции выводит информацию о пользователе в виде строк, используя два параметра.

Теперь мы можем вызвать функцию и назначить ей параметры:

profile.py

  def profile_info (имя пользователя, подписчики):
    print ("Имя пользователя:" + имя пользователя)
    print ("Подписчики:" + str (подписчики))

# Вызов функции с параметрами, указанными выше
profile_info ("саммышарк", 945)

# Вызов функции с ключевыми аргументами
profile_info (username = "AlexAnglerfish", подписчики = 342)

  

В первом вызове функции мы ввели информацию с именем пользователя sammyshark и подписчиками 945 , во втором вызове функции мы использовали аргументы ключевого слова, присваивая значения переменным аргумента.

Запустим программу:

  
  

Выход

Имя пользователя: sammyshark Подписчиков: 945 Имя пользователя: AlexAnglerfish Подписчиков: 342

Вывод показывает нам имена пользователей и количество подписчиков для обоих пользователей.

Это также позволяет нам изменять порядок параметров, как в этом примере той же программы с другим вызовом:

profile.py

  def profile_info (имя пользователя, подписчики):
    print ("Имя пользователя:" + имя пользователя)
    print ("Подписчики:" + str (подписчики))

# Изменить порядок параметров
profile_info (подписчики = 820, username = "cameron-catfish")

  

Когда мы снова запустим программу с профилем Python .py , мы получим следующий результат:

  

Выход

Имя пользователя: cameron-catfish Подписчиков: 820

Поскольку определение функции поддерживает тот же порядок print () операторов, если мы используем аргументы ключевого слова, не имеет значения, в каком порядке мы передаем их в вызов функции.

Значения аргументов по умолчанию

Мы также можем предоставить значения по умолчанию для одного или обоих параметров. Давайте создадим значение по умолчанию для параметра подписчиков со значением 1 :

.

профиль.py

  def profile_info (имя пользователя, подписчики = 1):
    print ("Имя пользователя:" + имя пользователя)
    print ("Подписчики:" + str (подписчики))
  

Теперь мы можем запускать функцию только с назначенной функцией имени пользователя, и количество подписчиков по умолчанию будет равно 1. Мы также можем изменить количество подписчиков, если захотим.

profile.py

  def profile_info (имя пользователя, подписчики = 1):
    print ("Имя пользователя:" + имя пользователя)
    print ("Подписчики:" + str (подписчики))

profile_info (username = "JOctopus")
profile_info (username = "sammyshark", подписчики = 945)
  

Когда мы запускаем программу с профилем Python .py , мы получим следующий результат:

  

Выход

Имя пользователя: JOctopus Подписчиков: 1 Имя пользователя: sammyshark Подписчиков: 945

Предоставление параметров по умолчанию со значениями может позволить нам пропустить определение значений для каждого аргумента, который уже имеет значение по умолчанию.

Возвращение значения

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

Функция может генерировать значение с помощью оператора return , который завершает функцию и , при необходимости, передает выражение обратно вызывающей стороне.Если вы используете оператор return без аргументов, функция вернет None .

До сих пор мы использовали оператор print () вместо оператора return в наших функциях. Давайте создадим программу, которая вместо печати будет возвращать переменную.

В новом текстовом файле с именем square.py мы создадим программу, которая возводит в квадрат параметр x и возвращает переменную y . Мы вызываем вызов для печати переменной result , которая формируется путем выполнения функции square () с переданным ей 3 .

square.py

  def квадрат (x):
    у = х ** 2
    вернуть y

результат = квадрат (3)
печать (результат)

  

Мы можем запустить программу и увидеть результат:

  
  

Выход

9

Целое число 9 возвращается как результат, чего мы и ожидаем, если попросим Python найти квадрат 3.

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

кв.py

  def квадрат (x):
    у = х ** 2
    # return y

результат = квадрат (3)
печать (результат)

  

А теперь давайте снова запустим программу:

  
  

Выход

Нет

Без использования здесь оператора return программа не может вернуть значение, поэтому значение по умолчанию равно None .

В качестве другого примера, в приведенной выше программе add_numbers.py мы могли заменить оператор print () на оператор return .

add_numbers.py

  def add_numbers (x, y, z):
    а = х + у
    б = х + г
    с = у + г
    вернуть a, b, c

суммы = add_numbers (1, 2, 3)
печать (суммы)

  

Вне функции мы устанавливаем переменную sums равной результату функции, принимающей 1 , 2 и 3 , как мы делали выше. Затем мы вызвали печать переменной сумм .

Давайте снова запустим программу, теперь она имеет оператор return :

  
  

Выход

(3, 4, 5)

Мы получаем те же числа 3 , 4 и 5 в качестве выходных данных, которые мы получили ранее, используя оператор print () в функции.На этот раз он доставляется в виде кортежа, потому что в списке выражений оператора return есть как минимум одна запятая.

Функции

завершаются немедленно, когда они попадают в оператор return , независимо от того, возвращают они значение или нет.

return_loop.py

  def loop_five ():
    для x в диапазоне (0, 25):
        печать (х)
        если x == 5:
            # Остановить функцию при x == 5
            возвращаться
    print («Эта строка не будет выполняться.»)

loop_five ()

  

Использование оператора return в цикле for завершает функцию, поэтому строка, выходящая за пределы цикла, не запускается.Если бы вместо этого мы использовали оператор break , в это время завершился бы только цикл, и была бы запущена последняя строка print () .

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

Использование

main () в качестве функции

Хотя в Python вы можете вызвать функцию внизу своей программы, и она будет запущена (как мы это делали в приведенных выше примерах), для многих языков программирования (таких как C ++ и Java) для выполнения требуется основная функция .Включение функции main () , хотя и не обязательно, может логически структурировать наши программы Python, объединяя наиболее важные компоненты программы в одну функцию. Это также может облегчить чтение наших программ программистам, не использующим Python.

Начнем с добавления функции main () в приведенную выше программу hello.py . Мы сохраним нашу функцию hello () , а затем определим функцию main () :

hello.py

  def hello ():
    print ("Привет, мир!")

def main ():
  

Давайте включим в функцию main () оператор print () , чтобы сообщить нам, что мы находимся в функции main () .Кроме того, давайте вызовем функцию hello () внутри функции main () :

hello.py

  def hello ():
    print ("Привет, мир!")


def main ():
    print («Это основная функция»)
    Привет()
  

Наконец, внизу программы мы вызовем функцию main () :

hello.py

  def hello ():
    print ("Привет, мир!")

def main ():
    print ("Это основная функция.")
    Привет()

основной()

  

На этом этапе мы можем запустить нашу программу:

  

Получим следующий результат:

  

Выход

Это основная функция.Привет мир!

Поскольку мы вызвали функцию hello () внутри main () , а затем вызвали только main () для запуска, Hello, World! текста печатается только один раз, после строки, которая сообщает нам, что мы находимся в основной функции.

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

В Python '__main__' - это имя области, в которой будет выполняться код верхнего уровня. Когда программа запускается из стандартного ввода, сценария или из интерактивной подсказки, ее __name__ устанавливается равным '__main__' .

По этой причине существует соглашение использовать следующую конструкцию:

 , если __name__ == '__main__':
    # Код для запуска, если это основная программа
  

Это позволяет использовать программные файлы:

  • в качестве основной программы и выполнить то, что следует за оператором if
  • как модуль и не запускать то, что следует за оператором if .

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

Давайте расширим нашу программу names.py выше и создадим новый файл с именем more_names.py . В этой программе мы объявим глобальную переменную и изменим нашу исходную функцию names () так, чтобы инструкции содержались в двух дискретных функциях.

Первая функция has_vowel () проверяет, содержит ли строка name гласную.

Вторая функция print_letters () будет печатать каждую букву строки name .

more_names.py

  # Объявить имя глобальной переменной для использования во всех функциях
name = str (input ('Введите свое имя:'))


# Определить функцию, чтобы проверить, содержит ли имя гласную
def has_vowel ():
    если установлено ('aeiou'). пересечение (name.ниже()):
        print ('Ваше имя содержит гласную.')
    еще:
        print ('Ваше имя не содержит гласных.')


# Перебрать буквы в строке имени
def print_letters ():
    на букву в имени:
        печать (письмо)
  

С такой настройкой давайте определим функцию main () , которая будет содержать вызов функций has_vowel () и print_letters () .

more_names.py

  # Объявить имя глобальной переменной для использования во всех функциях
name = str (input ('Введите свое имя:'))


# Определить функцию, чтобы проверить, содержит ли имя гласную
def has_vowel ():
    если установлено ('aeiou').пересечение (name.lower ()):
        print ('Ваше имя содержит гласную.')
    еще:
        print ('Ваше имя не содержит гласных.')


# Перебрать буквы в строке имени
def print_letters ():
    на букву в имени:
        печать (письмо)


# Определить основной метод, который вызывает другие функции
def main ():
    has_vowel ()
    print_letters ()
  

Наконец, мы добавим конструкцию if __name__ == '__main__': в конец файла. Для наших целей, поскольку мы поместили все функции, которые хотели бы выполнять, в функцию main () , мы вызовем функцию main () после этого оператора if .

more_names.py

  # Объявить имя глобальной переменной для использования во всех функциях
name = str (input ('Введите свое имя:'))


# Определить функцию, чтобы проверить, содержит ли имя гласную
def has_vowel ():
    если установлено ('aeiou'). пересечение (name.lower ()):
        print ('Ваше имя содержит гласную.')
    еще:
        print ('Ваше имя не содержит гласных.')


# Перебрать буквы в строке имени
def print_letters ():
    на букву в имени:
        печать (письмо)


# Определить основной метод, который вызывает другие функции
def main ():
    has_vowel ()
    print_letters ()


# Выполнить функцию main ()
если __name__ == '__main__':
    основной()

  

Теперь мы можем запустить программу:

  

Программа покажет тот же результат, что и имена .py , но здесь код более организован и может использоваться по модульному принципу без изменений.

Если вы не хотите объявлять функцию main () , в качестве альтернативы вы могли бы завершить программу следующим образом:

more_names.py

  ...
если __name__ == '__main__':
    has_vowel ()
    print_letters ()
  

Использование main () как функции и оператора if __name__ == '__main__': может организовать ваш код логическим образом, делая его более читаемым и модульным.

Заключение

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

Чтобы узнать больше о том, как сделать ваш код более модульным, вы можете прочитать наше руководство по написанию модулей на Python 3.

Определение вашей собственной функции Python - Настоящий Python