Содержание

Введение в 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.

синтаксис, логика и применение ~ 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—ArcGIS Pro

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

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

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

В следующем примере используются две функции ArcPy: GetParameterAsText для получения входного аргумента и Exists для определения, существует ли вход. Функция Exists возвращает логический аргумент (Истина (True) или Ложь (False)).

import arcpy

input = arcpy.GetParameterAsText(0)
if arcpy.Exists(input):
    print("Data exists")
else: 
    print("Data does not exist")

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

import arcpy
import os

# The workspace environment needs to be set before ListFeatureClasses
#    to identify which workspace the list will be based on
#   
arcpy.env.workspace = "c:/data"
out_workspace = "c:/data/results/"
clip_features = "c:/data/testarea/boundary.shp"

# Loop through a list of feature classes in the workspace
#
for fc in arcpy.ListFeatureClasses():
    # Set the output name to be the same as the input name, and 
    #    locate in the 'out_workspace' workspace
    #
    output = os.path.join(out_workspace, fc)

    # Clip each input feature class in the list
    #
    arcpy.Clip_analysis(fc, clip_features, output, 0.1)
Связанные разделы

Отзыв по этому разделу?

Интерактивный учебник языка Python

1. Функции

Напомним, что в математике факториал числа n определяется как n! = 1 ⋅ 2 ⋅ … ⋅ n. Например, 5! = 1 ⋅ 2 ⋅ 3 ⋅ 4 ⋅ 5 = 120. Ясно, что факториал можно легко посчитать, воспользовавшись циклом for. Представим, что нам нужно в нашей программе вычислять факториал разных чисел несколько раз (или в разных местах кода). Конечно, можно написать вычисление факториала один раз, а затем используя Copy-Paste вставить его везде, где это будет нужно.

	
# вычислим 3!
res = 1
for i in range(1, 4):
    res *= i
print(res)

# вычислим 5!
res = 1
for i in range(1, 6):
    res *= i
print(res)

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

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

Покажем, как написать функцию factorial(), которая принимает один параметр — число, и возвращает значение — факториал этого числа.

	
def factorial(n):
    res = 1
    for i in range(1, n + 1):
        res *= i
    return res

print(factorial(3))
print(factorial(5))

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

Далее идет тело функции, оформленное в виде блока, то есть с отступом. Внутри функции вычисляется значение факториала числа n и оно сохраняется в переменной res. Функция завершается инструкцией return res, которая завершает работу функции и возвращает значение переменной res.

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

Приведём ещё один пример. Напишем функцию max(), которая принимает два числа и возвращает максимальное из них (на самом деле, такая функция уже встроена в Питон).

10
20
def max(a, b):
    if a > b:
        return a
    else:
        return b

print(max(3, 5))
print(max(5, 3))
print(max(int(input()), int(input())))

Теперь можно написать функцию max3(), которая принимает три числа и возвращает максимальное их них.

	
def max(a, b):
    if a > b:
        return a
    else:
        return b

def max3(a, b, c):
    return max(max(a, b), c)

print(max3(3, 5, 4))
Встроенная функция max() в Питоне может принимать переменное число аргументов и возвращать максимум из них. Приведём пример того, как такая функция может быть написана.
	
def max(*a):
    res = a[0]
    for val in a[1:]:
        if val > res:
            res = val
    return res

print(max(3, 5, 4))
Все переданные в эту функцию параметры соберутся в один кортеж с именем a, на что указывает звёздочка в строке объявления функции.

2. Локальные и глобальные переменные

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

	
def f():
    print(a)

a = 1
f()

Здесь переменной a присваивается значение 1, и функция f() печатает это значение, несмотря на то, что до объявления функции f эта переменная не инициализируется. В момент вызова функции f() переменной a уже присвоено значение, поэтому функция f() может вывести его на экран.

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

Но если инициализировать какую-то переменную внутри функции, использовать эту переменную вне функции не удастся. Например:

	
def f():
    a = 1

f()
print(a)

Получим ошибку NameError: name 'a' is not defined. Такие переменные, объявленные внутри функции, называются локальными. Эти переменные становятся недоступными после выхода из функции.

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

	
def f():
    a = 1
    print(a)

a = 0
f()
print(a)

Будут выведены числа 1 и 0. Несмотря на то, что значение переменной a изменилось внутри функции, вне функции оно осталось прежним! Это сделано в целях “защиты” глобальных переменных от случайного изменения из функции. Например, если функция будет вызвана из цикла по переменной i, а в этой функции будет использована переменная i также для организации цикла, то эти переменные должны быть различными. Если вы не поняли последнее предложение, то посмотрите на следующий код и подумайте, как бы он работал, если бы внутри функции изменялась переменная i.

	
def factorial(n):
    res = 1
    for i in range(1, n + 1):
        res *= i
    return res

for i in range(1, 6):
    print(i, '! = ', factorial(i), sep='')
Если бы глобальная переменная i изменялась внутри функции, то мы бы получили вот что:
5! = 1
5! = 2
5! = 6
5! = 24
5! = 120
Итак, если внутри функции модифицируется значение некоторой переменной, то переменная с таким именем становится локальной переменной, и ее модификация не приведет к изменению глобальной переменной с таким же именем.

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

	
def f():
    print(a)
    if False:
        a = 0

a = 1
f()

Возникает ошибка: UnboundLocalError: local variable 'a' referenced before assignment. А именно, в функции f() идентификатор a становится локальной переменной, т.к. в функции есть команда, модифицирующая переменную a, пусть даже никогда и не выполняющийся (но интерпретатор не может это отследить). Поэтому вывод переменной a приводит к обращению к неинициализированной локальной переменной.

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

	
def f():
    global a
    a = 1
    print(a)

a = 0
f()
print(a)

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

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

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

5
def factorial(n):
    global f
    res = 1
    for i in range(2, n + 1):
        res *= i
    f = res

n = int(input())
factorial(n)
# дальше всякие действия с переменной f

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

Гораздо лучше переписать этот пример так:

5
# начало куска кода, который можно копировать из программы в программу
def factorial(n):
    res = 1
    for i in range(2, n + 1):
        res *= i
    return res
# конец куска кода

n = int(input())
f = factorial(n)
# дальше всякие действия с переменной f

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

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

3. Рекурсия

def short_story():
    print("У попа была собака, он ее любил.")
    print("Она съела кусок мяса, он ее убил,")
    print("В землю закопал и надпись написал:")
    short_story()

Как мы видели выше, функция может вызывать другую функцию. Но функция также может вызывать и саму себя! Рассмотрим это на примере функции вычисления факториала. Хорошо известно, что 0!=1, 1!=1. А как вычислить величину n! для большого n? Если бы мы могли вычислить величину (n-1)!, то тогда мы легко вычислим n!, поскольку n!=n⋅(n-1)!. Но как вычислить (n-1)!? Если бы мы вычислили (n-2)!, то мы сможем вычисли и (n-1)!=(n-1)⋅(n-2)!. А как вычислить (n-2)!? Если бы… В конце концов, мы дойдем до величины 0!, которая равна 1. Таким образом, для вычисления факториала мы можем использовать значение факториала для меньшего числа. Это можно сделать и в программе на Питоне:

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

print(factorial(5))

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

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

  1. Неправильное оформление выхода из рекурсии. Например, если мы в программе вычисления факториала забудем поставить проверку if n == 0, то factorial(0) вызовет factorial(-1), тот вызовет factorial(-2) и т. д.
  2. Рекурсивный вызов с неправильными параметрами. Например, если функция factorial(n) будет вызывать factorial(n), то также получится бесконечная цепочка.

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

Ссылки на задачи доступны в меню слева. Эталонные решения теперь доступны на странице самой задачи.

Функции в программировании. Курс «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: 7 примеров. Базовые, встроенные и пользовательские функции

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

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

Базовые функции Python

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

#определяем и объявляем функцию
def calculate_sum(a,b):
  sum = a+b
  return sum

#инструкция, приведённая ниже, называется вызовом функции
print(calculate_sum(2,3)) # 5

Кроме того, в Python есть встроенные и пользовательские функции.

Пользовательские функции Python

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

def calculate_si_amount(principal, rate, time):
  interest =  (principal*rate*time)/100
  return principal+interest

В данной функции окончательная сумма может быть рассчитана посредством использования простого процента к основной сумме. Именем функции является Calculate_si_amount. Что касается principal, time и rate — то это параметры, а функция возвращает рассчитанные данные.

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

from random import seed, random
from random import random

def generate_random_number():
  seed(10)
  return random()

Встроенные функции Python

В Python существует много встроенных функций. Одна из наиболее часто используемых — print(). Её работа чрезвычайно проста:

print("Всем привет")
print(len("Меня зовут Андрей"))

Ещё популярны такие функции, как len(),abs(), sum(), str(), int() и другие.

Параметры функции в Python

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

def multiply(a, b=10):
  return a*b

multiply(12) # 120
multiply(2, 3) # 6
multiply(b=9) # Ошибка: None*9 недопустимо

В вышеописанной функции, когда пользователь не задает 2-й параметр b, он предполагает, что параметр равен 10, однако при этом нужно предоставить 1-й параметр.

Неизвестное количество параметров в функции Python

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

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

def calculate_sum(a, *args):
  sum = a
  for i in args:
    sum += i
  return sum

calculate_sum(10) # 10
calculate_sum(10, 11, 12) # 33
calculate_sum(1, 2, 94, 6, 2, 8, 9, 20, 43, 2) # 187

Так же **kwargs ожидает словарь в качестве параметра.

def print_names(f1, l1, **kwargs):
  print(f1, l1, end=' ')
  for key in kwargs:
    print(key, kwargs[key], end=' ')

print_names("andrey", "master")
print_names("andrey", "master", alex="john", leon="elene")
# andrey master andrey master alex john leon elene

Обратите внимание, что фрагмент выше имеет ссылку на цикл for.

Тип данных для возвращаемого значения и параметров в Python

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

def prime_numbers(x:int) -> (int, list):
  l=[]
  for i in range(x+1):
    if checkPrime(i):
      l.append(i)
  return len(l), l

В нашем примере определение функции указывает, что нужен 1 параметр типа int и вернёт два значения типа list и int соответственно.

Возвращаемое значение функции в Python

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

def prime_numbers(x):
  l=[]
  for i in range(x+1):
    if checkPrime(i):
      l.append(i)
  return len(l), l

no_of_primes, primes_list = prime_numbers(100)

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

PostgreSQL : Документация: 9.6: 44.2. Функции на PL/Python : Компания Postgres Professional

44.2. Функции на PL/Python

Функции на PL/Python объявляются стандартным образом с помощью команды CREATE FUNCTION:

CREATE FUNCTION funcname (argument-list)
  RETURNS return-type
AS $$
  # Тело функции на PL/Python
$$ LANGUAGE plpythonu;

Тело функции содержит просто скрипт на языке Python. Когда вызывается функция, её аргументы передаются в виде элементов списка args; именованные аргументы также передаются скрипту Python как обычные переменные. С применением именованных аргументов скрипт обычно лучше читается. Результат из кода Python возвращается обычным способом, командой return или yield (в случае функции, возвращающей множество). Если возвращаемое значение не определено, Python возвращает None. Исполнитель PL/Python преобразует None языка Python в значение NULL языка SQL.

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

CREATE FUNCTION pymax (a integer, b integer)
  RETURNS integer
AS $$
  if a > b:
    return a
  return b
$$ LANGUAGE plpythonu;

Код на Python, заданный в качестве тела объявляемой функции, становится телом функции Python. Например, для показанного выше объявления получается функция:

def __plpython_procedure_pymax_23456():
  if a > b:
    return a
  return b

Здесь 23456 — это OID, который PostgreSQL присвоил данной функции.

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

CREATE FUNCTION pystrip(x text)
  RETURNS text
AS $$
  x = x.strip()  # ошибка
  return x
$$ LANGUAGE plpythonu;

так как присвоение x значения делает x локальной переменной для всего блока, и при этом x в правой части присваивания оказывается ещё не определённой локальной переменной x, а не параметром функции PL/Python. Добавив оператор global, это можно исправить:

CREATE FUNCTION pystrip(x text)
  RETURNS text
AS $$
  global x
  x = x.strip()  # теперь всё в порядке
  return x
$$ LANGUAGE plpythonu;

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

функций 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» )

Попробуй сам »

Аргументы часто сокращаются до args в документации 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)

Попробуй сам »

Возвращаемые значения

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

Пример

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 Лямбда


Лямбда-функция — это небольшая анонимная функция.

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


Синтаксис

лямбда аргументы : выражение

Выражение выполняется и возвращается результат:

Пример

Добавьте 10 к аргументу a , и вернуть результат:

x = лямбда a: a + 10
печать (x (5))

Попробуй сам »

Лямбда-функции могут принимать любое количество аргументов:

Пример

Умножить аргумент на на аргумент b и верните результат:

x = лямбда a, b: a * b
print (x (5, 6))

Попробуй сам »

Пример

Обобщить аргумент a , b и c и вернуть результат:

x = лямбда a, b, c: a + b + c
print (x (5, 6, 2))

Попробуй сам »

Зачем нужны лямбда-функции?

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

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

def myfunc (n):
вернуть лямбда a: a * n

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

Пример

определение myfunc (n):
вернуть лямбда a: a * n

mydoubler = myfunc (2)

print (mydoubler (11))

Попробуй сам »

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

Пример

определение myfunc (n):
вернуть лямбда a: a * n

mytripler = myfunc (3)

print (mytripler (11))

Попробуй сам »

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

Пример

определение myfunc (n):
вернуть лямбда a: a * n

mydoubler = myfunc (2)
mytripler = myfunc (3)

print (mydoubler (11))
принт (mytripler (11))

Попробуй сам »

Используйте лямбда-функции, когда анонимная функция требуется на короткий период времени.




Встроенные функции — документация Python 3.9.6

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

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

режим — дополнительная строка, указывающая режим, в котором файл открыт. По умолчанию это 'r' , что означает открытие для чтения в текстовом режиме. Другие общие значения: 'w' для записи (усечение файла, если он уже существует), 'x' для исключительного создания и 'a' для добавления (что на некоторых системах Unix означает, что все записи добавляются в конец файл независимо от текущей позиции поиска).В текстовом режиме, если Кодировка не указана, используемая кодировка зависит от платформы: locale.getpreferredencoding (False) вызывается для получения текущей локали кодирование. (Для чтения и записи сырых байтов используйте двоичный режим и оставьте кодировка не указана.) Доступные режимы:

Знак

Значение

'r'

открыто для чтения (по умолчанию)

'ширина'

открыт для записи, сначала обрезка файла

'x'

открыто для монопольного создания, ошибка, если файл уже существует

'а'

открыто для записи, добавляется в конец файла, если он существует

'b'

двоичный режим

't'

текстовый режим (по умолчанию)

'+'

открыт для обновления (чтение и запись)

Режим по умолчанию — '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 () возвращает Истина ) использовать буферизацию строки. Другие текстовые файлы используют политику описано выше для двоичных файлов.

кодировка — это имя кодировки, используемой для декодирования или кодирования файла. Это следует использовать только в текстовом режиме. Кодировка по умолчанию — платформа. зависимый (независимо от локали .getpreferredencoding () возвращает), но любой кодировка текста, поддерживаемая Python может быть использован. См. Модуль кодеков для список поддерживаемых кодировок.

ошибок — необязательная строка, определяющая способ кодирования и декодирования. ошибки должны обрабатываться — это не может использоваться в двоичном режиме. Доступны различные стандартные обработчики ошибок. (перечислены в разделе «Обработчики ошибок»), хотя любые имя обработки ошибок, которое было зарегистрировано с codecs.register_error () также допустим.Стандартные имена включают:

  • 'strict' , чтобы вызвать исключение ValueError , если есть ошибка кодировки. Значение по умолчанию Нет имеет то же самое эффект.

  • 'ignore' игнорирует ошибки. Обратите внимание, что игнорирование ошибок кодирования может привести к потере данных.

  • 'replace' вызывает вставку маркера замены (например, '?' ) где есть искаженные данные.

  • 'surrogateescape' будет представлять любые неправильные байты как код точек в области частного использования Unicode в диапазоне от U + DC80 до U + DCFF.Эти частные кодовые точки будут затем снова превращены в те же байты при использовании обработчика ошибок суррогата при записи данных. Это полезно для обработки файлов в неизвестная кодировка.

  • 'xmlcharrefreplace' поддерживается только при записи в файл. Символы, не поддерживаемые кодировкой, заменяются символами ссылка на соответствующий символ XML & # nnn; .

  • 'backslashreplace' заменяет искаженные данные на обратную косую черту Python escape-последовательности.

  • 'namereplace' (также поддерживается только при записи) заменяет неподдерживаемые символы управляющими последовательностями \ N {...} .

новая строка управляет тем, как работает универсальный режим новой строки (только относится к текстовому режиму). Это может быть None , '' , '\ n' , '\ r' и '\ r \ n' . Работает следующим образом:

  • При чтении ввода из потока, если перевод строки равен Нет , универсальный Режим новой строки включен.Строки на входе могут заканчиваться на '\ n' , '\ r' или '\ r \ n' , и они переводятся в '\ n' перед возвращаются вызывающему абоненту. Если это '' , универсальный режим новой строки включен, но окончания строк возвращаются вызывающему абоненту без перевода. Если это имеет любое из других допустимых значений, строки ввода заканчиваются только заданная строка, и конец строки возвращается вызывающему абоненту без перевода.

  • При записи вывода в поток, если новая строка - это Нет , любое '\ n' написанные символы переводятся в системный разделитель строк по умолчанию, ос.linesep . Если новая строка - '' или '\ n' , перевода нет происходит. Если новая строка - любое другое допустимое значение, любое '\ n' написанные символы переводятся в заданную строку.

Если closefd - Ложь и был указан дескриптор файла, а не имя файла. задано, базовый дескриптор файла будет оставаться открытым, когда файл закрыто. Если указано имя файла closefd должно быть True (по умолчанию) в противном случае возникнет ошибка.

Можно использовать настраиваемый открыватель, передав вызываемый объект как opener . Лежащий в основе файловый дескриптор для файлового объекта затем получается путем вызова открывателя с ( файл , флаги ). открыватель должен возвращать дескриптор открытого файла (передавая 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 () используется для открытия файла в тексте режим ( '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:
  • Добавлен параметр открывателя .

  • Добавлен режим 'x' .

  • Вызывалось IOError , теперь это псевдоним OSError .

  • FileExistsError теперь возникает, если файл открывается в монопольном режиме. режим создания ( 'x' ) уже существует.

Устарело с версии 3.4, будет удалено в версии 3.10: режим 'U' .

Изменено в версии 3.5:
  • Если системный вызов прерывается и обработчик сигнала не вызывает исключение, функция теперь повторяет системный вызов вместо того, чтобы вызывать InterruptedError исключение (объяснение см. В PEP 475 ).

  • Добавлен обработчик ошибок namereplace .

Python-функций (def): определение с примерами

Что такое функция в Python?

В Python функция - это группа связанных операторов, выполняющих определенную задачу.

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

Кроме того, он позволяет избежать повторения и позволяет многократно использовать код.

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

def имя_функции (параметры):
"" "строка документации" ""
выписка (а) 

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

  1. Ключевое слово def , которое отмечает начало заголовка функции.
  2. Имя функции, однозначно идентифицирующее функцию. Именование функций следует тем же правилам написания идентификаторов в Python.
  3. Параметры (аргументы), через которые мы передаем значения функции. Они не обязательны.
  4. Двоеточие (:) для обозначения конца заголовка функции.
  5. Необязательная строка документации (docstring), описывающая, что делает функция.
  6. Один или несколько допустимых операторов Python, составляющих тело функции.Заявления должны иметь одинаковый уровень отступа (обычно 4 пробела).
  7. Необязательный оператор return для возврата значения из функции.

Пример функции

  def greet (имя):
    "" "
    Эта функция приветствует
    человек прошел как
    параметр
    "" "
    print («Привет,» + имя + «. Доброе утро!»)  

Как вызвать функцию в Python?

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

  >>> привет ('Павел')
Привет, Пол. Доброе утро!  

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

  def greet (имя):
    "" "
    Эта функция приветствует
    человек прошел как
    параметр
    "" "
    print ("Привет," + имя + ". Доброе утро!")

привет ('Павел')  

Строки документации

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

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

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

Например :

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

  >>> печать (привет .__ doc__)

    Эта функция приветствует
    человек прошел как
    параметр  

Чтобы узнать больше о строках документации в Python, посетите страницу Python Docstrings.


Отчет о возврате

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

Синтаксис возврата

возврат [список_выражений] 

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

Например:

  >>> print (привет («май»))
Привет, май. Доброе утро!
Нет  

Здесь None - это возвращаемое значение, поскольку greet () напрямую печатает имя, а оператор return не используется.


Пример возврата

  def absolute_value (число):
    "" "Эта функция возвращает абсолютное
    значение введенного числа "" "

    если число> = 0:
        вернуть номер
    еще:
        return -num


печать (абсолютное_значение (2))

печать (абсолютное_значение (-4))  

Выход

  2
4  

Как функция работает в Python?

Работа функций в Python

Объем и время жизни переменных

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

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

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

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

  def my_func ():
х = 10
print ("Значение внутри функции:", x)

х = 20
my_func ()
print ("Значение вне функции:", x)  

Выход

  Значение внутри функции: 10
Значение вне функции: 20  

Здесь мы видим, что значение x изначально равно 20. Несмотря на то, что функция my_func () изменила значение x на 10, это не повлияло на значение вне функции.

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

С другой стороны, переменные вне функции видны изнутри. У них глобальный размах.

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


Типы функций

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

  1. Встроенные функции - Функции, встроенные в Python.
  2. Пользовательские функции - Функции, определяемые самими пользователями.

Определение вашей собственной функции Python - Настоящий Python