изменить глобальную переменную во время выполнения для импортируемой функции - PullRequest
0 голосов
/ 15 октября 2018

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

one_file.py

import time
import threading
has_run = False

def processing_function():
    global has_run
    time.sleep(5)
    has_run = True

start = time.clock()

thread = threading.Thread(target=processing_function)
thread.start()

while True:
    print(has_run)
    time.sleep(0.5)
    if (10/3600) < time.clock() - start:
        break

При запуске это на некоторое время напечатает False, затем начнет печатать True.

Я пытался заставить это работать с двумя файлами, подобными этому:

file1.py

import time
has_run = False

def processing_function():
    global has_run
    time.sleep(5)
    has_run = True

file2.py

from file1 import processing_function, has_run
import time
import threading

start = time.clock()
thread = threading.Thread(target=processing_function)
thread.start()

while True:
    print(has_run)
    time.sleep(0.5)
    if (10/3600) < time.clock() - start:
        break

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

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

Ответы [ 2 ]

0 голосов
/ 15 октября 2018

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

while True:
    print(file1.has_run)
    ...

(Это потому, что processing_function назначает новое значение глобальному, а немутирование существующего значения.)

Вы можете наблюдать это на гораздо более простом примере.Рассмотрим очень простой модуль tmp1:

x = 3

Теперь посмотрим, как from tmp1 import x создает глобальную переменную, значение которой не зависит от tmp1.x:

>>> import tmp1
>>> from tmp1 import x
>>> x
3
>>> tmp1.x
3
>>> x = 6
>>> tmp1.x
3
>>> tmp1.x = 5
>>> tmp1.x
5
>>> x
6
>>>
0 голосов
/ 15 октября 2018

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

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

...