Как обратиться к переменной из другой функции python

от admin

Как в функции сослаться на переменную другой функции?

Python 3. PyQt4
Условная модель вопроса:
Есть функция «аа» с переменными. Я хочу в функции «bb» использовать эти переменные вот так:

Обе функции принадлежат классу QWidget.
В реале мой вопрос выглядит так:

Т.е. во второй функции надо воспользоваться переменной из первой функции — кат_index

  • Вопрос задан более трёх лет назад
  • 2088 просмотров

Оценить 6 комментариев

  • Facebook
  • Вконтакте
  • Twitter

кириллица в имени переменной

Pyrym

sim3x

Pyrym

Djaler

Pyrym

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

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

Замыкания в Python

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

В этом примере мы объявили функцию display() внутри функции say() . Функция display() — вложенная.

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

В Python такие переменные как greeting называются свободными переменными.

На самом деле функция display() состоит из двух частей:

  • Сама функция display() .
  • Переменная greeting , в которой содержится значение «Привет» .

Так вот все вместе это называется замыканием (closure).

Замыкание (closure) — это вложенная функция, которая ссылается на одну или более переменных из объемлющей (enclosing) области видимости.

Можно вернуть функцию из функции

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

В этом примере функция say() возвращает функцию display() , а не выполняет ее.

Когда say() возвращает display() , на самом деле возвращается замыкание:

Следующая инструкция присваивает возвращаемое значение функции say() переменной fn . Поскольку fn — это функция, ее можно вызвать:

Функция say() выполняется и возвращает функцию fn() . Когда выполняется fn() , функция say() уже завершила выполнение.

Это значит, что область видимости функции say() уже не существует к тому моменту, когда выполняется fn() .

Поскольку переменная greeting принадлежит области видимости функции say() , она, по идеи, тоже должна уничтожаться после выполнения say() .

Однако fn() все равно как-то выводит значение переменной greeting , как вы видите в примере выше.

Разберемся, как это работает и почему так происходит.

Ячейки и переменные с несколькими областями видимости

Переменная greeting «разделяется» между двумя областями видимости:

  • Функции say() .
  • Замыкания.

То есть greeting находится одновременно в двух областях видимости. Тем не менее, она всегда ссылается на один и тот же строковый объект «Привет» .

Для этого Python создает промежуточный объект — ячейку (cell).

Узнать адрес ячейки в памяти можно через свойство __closure__ , как показано ниже:

Вывод

__closure__ возвращает кортеж ячеек.

В этом примере адрес ячейки в памяти — 0x0000017184915C40 . Она ссылается на строковый объект по адресу 0x0000017186A829B0 .

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

Вывод

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

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

На основе этого механизма можно определить замыкание по-другому:

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

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

В этом примере fn.__code__.co_freevars вернет переменную greeting — единственную свободную переменную в замыкании fn .

Когда Python сам создает замыкания

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

1. Сначала определим функцию multiplier() , которая возвращает замыкание:

Функция multiplier() возвращает произведение двух аргументов. Но возвращается не само произведение, а замыкание.

2. Теперь вызовем функцию multiplier() три раза:

Вызовы функция создадут три замыкания. Каждая функция умножает число на 1, 2, и 3 соответсвенно.

3. А теперь выполним функции замыканий:

Вывод

Как вы видите, у m1 , m2 и m3 разные инстансы замыкания.

Читать:
Potplayer как добавить звуковую дорожку

Замыкания и цикл for

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

Что мы здесь делаем

  1. Объявляем список, в котором будем хранить замыкания.
  2. Используем лямбда-выражение, чтобы создать замыкание, и добавляем его в список на каждой итерации.
  3. «Распоковываем» замыкания из списка и присваиваем их переменным m1 , m2 и m3 соответсвенно.
  4. Передаем значения 10, 20 и 30 в каждое замыкание и выполняем их.

Вывод

Работает не так, как мы ожидали. Почему?

В цикле for x меняет значения от 1 до 3. Когда цикл завершается, значение x — 3.

Каждый элемент списка — соответсвующее замыкание lambda y: x*y .

Python использует значение x для вычислений каждый раз, когда вы вызываются m1(1) , m2(10) и m3(10) . И поскольку в момент выполнения замыкания x всегда 3, результат всех замыканий одинаковый — 30.

Чтобы исправить эту проблему, нужно объяснить Python, что значение x для вычислений нужно использовать в цикле.

Как обратиться к переменной из другого модуля в PYTHON 3

Мне надо завести в main переменную, которую я смогу изменять в sub. Проблема в том, что sub импортируется в main и при добавлении строчки from main import charts (где charts — нужная мне константа) получается ошибка, как я понимаю, связанная с зацикленным импортом.

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

main.py

sub.py

Ответы (2 шт):

main.py

sub.py

1) Можно создать глобальную переменную

2) Можно создать используя @property и .setter, и сразу при обновлении переменной выполнять метод

Как обратиться к переменной из другой функции python

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Похожие статьи