Python передача данных между функциями

Python передача данных между функциями

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

def say_hello(): print("Hello") def say_goodbye(): print("Good Bye") message = say_hello message() # Hello message = say_goodbye message() # Good Bye

В данном случае переменной message присваивается одна из функций. Сначала ей передается функция say_hello() :

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

Фактически это приведет к выполнению функции say_hello, и на консоль будет выведена строка «Hello». Затем подобным образом мы можем передать переменной message другую функцию и вызвать ее.

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

def sum(a, b): return a + b def multiply(a, b): return a * b operation = sum result = operation(5, 6) print(result) # 11 operation = multiply print(operation(5, 6)) # 30

Функция как параметр функции

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

def do_operation(a, b, operation): result = operation(a, b) print(f"result = ") def sum(a, b): return a + b def multiply(a, b): return a * b do_operation(5, 4, sum) # result = 9 do_operation(5, 4, multiply) # result = 20

В данном случае функция do_operation имеет три параметра, причем третий параметр, как предполагается, будет представлять функцию, которая принимает два параметра и возвращает некоторый результат. Иными словами третий параметр — operation представляет некоторую операцию, но на момент определения функции do_operation мы точно не знаем, что это будет за операция. Мы только знаем, что она принимает два параметр и возвращает какой-то результат, который потом выводится на консоль.

Читайте также:  Parse words in python

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

То есть в данном случае параметр operation фактически будет представлять функцию sum и будет возвращать сумму дву чисел.

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

do_operation(5, 4, multiply) # result = 20

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

Функция как результат функции

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

def sum(a, b): return a + b def subtract(a, b): return a - b def multiply(a, b): return a * b def select_operation(choice): if choice == 1: return sum elif choice == 2: return subtract else: return multiply operation = select_operation(1) # operation = sum print(operation(10, 6)) # 16 operation = select_operation(2) # operation = subtract print(operation(10, 6)) # 4 operation = select_operation(3) # operation = multiply print(operation(10, 6)) # 60

В данном случае функция select_operation в зависимости от значения параметра choice возвращает одну из трех функций — sum, subtract и multiply. Затем мы мы можем получить результат функции select_operation в переменную operation:

operation = select_operation(1)

Так, в данном случае в функцию select_operation передается число 1, соответственно она будет возвращать функцию sum. Поэтому переменная operation фактически будет указывать на функцию sum, которая выполняет сложение двух чисел:

print(operation(10, 6)) # 16 - фактически равно sum(10, 6)

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

Источник

Что вы не знали и передаче параметров в функции

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

Передача параметров в других языках

Многие языки программирования предлагают две модели передачи параметров в функции/процедуры:

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

Использует ли Python модель передачи по значению?

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

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

def foo(x): x = 4 a = 3 foo(a) print(a) # 3

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

def clearly_not_pass_by_value(my_list): my_list[0] = 42 l = [1, 2, 3] clearly_not_pass_by_value(l) print(l) # [42, 2, 3]

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

Использует ли Python передачу по ссылке?

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

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

def not_pass_by_reference(my_list): my_list = [42, 73, 0] l = [1, 2, 3] not_pass_by_reference(l) print(l) # [1, 2, 3]

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

Объекты в Python

В Python всё является объектом. Каждый объект характеризуется следующими характеристиками:

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

Эти характеристики можно узнать следующим образом:

>>> id(obj) 2698212637504 >>> type(obj) >>> obj [1, 2, 3]

Эти знания нам пригодятся в дальнейшем.

Изменяемые и неизменяемые объекты

Объекты в Python могут быть изменяемыми (mutable) или неизменяемыми (immutable). Это свойство полностью зависит от типа объекта. Иными словами, не/изменяемость является характеристикой типа, а не конкретных объектов.

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

Список (list) является изменяемым типом данных. Почему? Потому что списки являются контейнерами: в них можно добавлять данные и из можно удалять данные. Иными словами, их можно спокойно изменять.

Ниже приведен пример того, как содержимое списка меняется, но идентификатор остается тем же самым, что бы мы ни делали.

>>> obj = [] >>> id(obj) 2287844221184 >>> obj.append(0); obj.extend([1, 2, 3]); obj [42, 0, 1, 2, 3] >>> id(obj) 2287844221184 >>> obj.pop(0); obj.pop(0); obj.pop(); obj 42 0 3 [1, 2] >>> id(obj) 2287844221184

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

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

>>> [].append(0) # Ничего не возвращается >>> "Hello, world!".upper() # Возвращается новая строка 'HELLO, WORLD!"

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

>>> obj[0] 'H' >>> obj[0] = "h" Traceback (most recent call last): File "", line 1, in TypeError: 'str' object does not support item assignment

Для справки, в Python встроенные типы:

Переменные и их имя

Ещё необходимо понять, что название переменной — это не то же самое, что и сам объект. Например, имя obj был просто некой меткой, которая была связана с объектом с идентификатором 2287844221184 , типом list и содержимым 1, 2, 3 . Это называется механизмом связывания, о котором мы говорил тут.

Мы вольны связывать и другие метки к этому же самому объекту:

>>> foo = bar = baz = obj >>> id(foo) 2698212637504 >>> id(bar) 2698212637504 >>> id(baz) 2698212637504 >>> id(obj) 2698212637504 # При этом, если изменить объект: >>> obj = 5 >>> id(obj) 94830320197056

Как видим все метки обращаются к одному объекту. В Python даже есть специальный оператор is , который проверяет являются ли два объекты одной сущностью (читай: равны ли их id ).

>>> foo is obj True >>> bar is foo True >>> obj is foo True

Изменяя содержимое через одну переменную, эти изменения можно пронаблюдать через другие, поскольку это один и тот же объект. При этом нужно понимать, объекты, которые имеют тот же тип и содержимое, но не id , не являются одним объектом:

В Python используется передача параметров через присваивание

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

Так, если мы передаем неизменяемые параметр (например, int ), то у нас нет возможности хоть как-то его изменить. Каждый раз, когда используется присваивание, то создается новый объект, хоть и имеющий то же самое имя. Взгляните на данный пример:

def foo(bar): bar = 3 return bar a = 5 foo(a)

Вызов функции для неизменяемого типа подразумевает, что используется связывание bar = 5 . Сразу после этого в теле функции осуществляется второе связывание bar = 3 . Но все эти объекты разные. Поэтому при использовании неизменяемых объектов в качестве параметров, их передача осуществляется как будто по схеме передаче значений.

Источник

Как передать результат функции в другую функцию, python?

Осваиваю классы, ооп, но пока запутано. В голове путаются тропинки путешествия данных с одного метода в другой, третий и т.д,
Практикую, ставлю разные задачи и пытаюсь выполнить..
вот код — https://jsbin.com/nitocu/edit?js

Tash1moto

#coding:utf-8 class MyClass: def __init__(self,x,y,z): self.x=x self.y=y self.z=z def calc_method(self,x,y,z): return (x + y/z) def printing_calc_result(calc_method): print calc_method # - хочу показать результат подсчета а не показать то что это функция) ########################################## root = MyClass(150,60,40) root.printing_calc_result()

доступ к методам тоже можно осуществлять по self. и в методы передавать свойства класса не надо им о свойствах изветсно
class MyClass:

def __init__(self,x,y,z):
self.x=x
self.y=y
self.z=z

def calc_method(self):
return (self.x + self.y/self.z)

def printing_calc_result(self):
print (self.calc_method() )# — хочу показать результат подсчета а не показать то что это функция)

root = MyClass(150,60,40)
root.printing_calc_result()

Tash1moto

все стало ясно а именно self.calc_method() — то что нужно в данном случае.
Не просто представить с первого раза как работает self.

Источник

Оцените статью