#python
#python
Вопрос:
Недавно я пытался создать самодельный считыватель «дискового пространства». Я создал библиотеку, которая хранит значения в списке «диск», и когда я выполняю подпроцесс нового скрипта для записи на «диск», чтобы увидеть, изменяются ли значения на дисплее, ничего не происходит. Я понял, что каждый раз, когда вы импортируете модуль, модуль как бы клонирует себя только к этому сценарию.
Я хочу, чтобы скрипты могли импортировать один и тот же модуль, и чтобы, если 1 скрипт изменяет значение, другой скрипт мог видеть это значение.
Вот мой код для «дисковой» системы
import time
ram = []
space = 256000
lastspace = 0
for i in range(0,space 1):
ram.append('')
def read(location):
try:
if ram[int(location)] == '':
return "ERR_NO_VALUE"
else:
return ram[int(location)]
except:
return "ERR_OUT_OF_RANGE"
def write(location, value):
try:
ram[int(location)] = value
except:
return "ERR_OUT_OF_RANGE"
def getcontents():
contents = []
for i in range(0, 256001):
contents.append([str(i) '- ', ram[i]])
return contents
def getrawcontents():
contents = []
for i in range(0, 256001):
contents.append(ram[i])
return contents
def erasechunk(beg, end):
try:
for i in range(int(beg), int(end) 1):
ram[i] = ''
except:
return "ERR_OUT_OF_RANGE"
def erase(location):
ram[int(location)] = ''
def reset():
ram = []
times = space/51200
tc = 0
for i in range(0,round(times)):
for x in range(0,51201):
ram.append('')
tc = 1
print("Byte " str(tc) " of " " Bytes")
for a in range(0,100):
print('a', end='')
return [len(ram), ' bytes']
def wipe():
for i in range(0,256001):
ram[i] = ''
return "WIPED"
def getspace():
x = 0
for i in range(0,len(ram)):
if ram[i] != "":
x = 1
return [x,256000]
Комментарии:
1. Проблема в том, как вы вызываете этот скрипт, а не в самом скрипте, пожалуйста, измените его, чтобы показать минимальный пример того, где вызов этих функций вызывает у вас проблему? т. е. Где вы «подпроцессируете новый скрипт для записи на «диск» `. Если у вас есть два полностью независимых файла .py, отдельно импортирующих приведенный выше код, они не смогут каким-либо образом взаимодействовать друг с другом.
Ответ №1:
Самый короткий ответ на ваш вопрос, который я понимаю как «если я import
разделяю одну и ту же функцию на две (или более) Пространства имен Python, могут ли они взаимодействовать друг с другом?», нет. Что на самом деле происходит, когда вы import
используете модуль, так это то, что Python использует исходный скрипт для «сборки» этих функций в пространстве имен, в которое вы их импортируете; нет никакого смысла постоянства в том, «откуда взялся модуль», поскольку этот исходный модуль фактически нигде не запускается в процессе Python! Когда вы используете import
эти функции в нескольких сценариях, он просто создаст эти псевдоглобальные переменные (в вашем случае ram
) с импортируемой функцией.
import
Документы Python: https://docs.python.org/3/reference/import.html
Вся страница модели данных Python, включая то, что __globals__
означает для функций и модулей: https://docs.python.org/3/reference/datamodel.html
Объяснение:
Чтобы углубиться, когда вы импортируете любую из функций из этого скрипта (предположим, он называется ‘disk.py ‘), вы получите объект в __globals__
вызываемом dict этой функции ram
, который действительно будет работать так, как вы ожидаете для этих функций в вашем текущем пространстве имен:
from disk import read,write
write(13,'thing')
print(read(13)) #prints 'thing'
Мы могли бы предположить, поскольку эти функции точно обращаются к нашему ram
объекту, что ram
объект каким-то образом модифицируется в пространстве имен исходного скрипта, к которому затем может быть доступен другой скрипт (другой процесс Python). Просмотр пространства имен нашего текущего скрипта, использующего dir()
, может поддержать это понятие, поскольку мы видим только read
and write
, а не ram
. Но секрет в том, что ram
скрыто в __globals__
dict этих функций (упомянуто выше), то есть как функции взаимодействуют с ram
:
from disk import read,write
print(type(write.__globals__['ram'])) #<class 'list'>
print(write.__globals__['ram'] is read.__globals__['ram']) #True
write(13,'thing')
print(read(13)) #'thing'
print(read.__globals__['ram'][13]) #'thing'
Как вы можете видеть, ram
actually — это переменная, определенная в пространстве имен нашего текущего процесса Python, скрытая в __globals__
dict функций, которая на самом деле является точно таким же словарем для любой функции, импортированной из того же модуля; read.__globals__ is write.__globals__
оценивается как True (даже если вы не импортируете их одновременно!).
Итак, чтобы завершить все это, ram
содержится в __globals__
dict для disk
модуля, который создается отдельно в пространстве имен каждого процесса, в который вы импортируете:
Интерпретатор Python # 1:
from disk import read,write
print(id(read.__globals__),id(write.__globals__)) #139775502955080 139775502955080
Интерпретатор Python # 2:
from disk import read,write
print(id(read.__globals__),id(write.__globals__)) #139797009773128 139797009773128
Подсказка по решению:
Существует много подходов к тому, как сделать это практически, которые выходят за рамки этого ответа, но я предположу, что pickle
это стандартный способ отправки объектов между интерпретаторами Python с использованием файлов и имеет действительно стандартный интерфейс. Вы можете просто записывать, читать и т. Д. Свой ram
объект, Используя файл pickle. Для записи:
import pickle
with open('./my_ram_file.pkl','wb') as ram_f:
pickle.dump(ram,ram_f)
Для чтения:
import pickle
with open('./my_ram_file.pkl','rb') as ram_f:
ram = pickle.load(ram_f)
Комментарии:
1. Хорошо, это имеет гораздо больше смысла. Я собираюсь попробовать.