Python импорт из байтового ввода-вывода (или, в более общем случае, из объекта в памяти) - PullRequest
4 голосов
/ 12 апреля 2020

Контекст:

В настоящее время у меня есть программа, которая загружает набор плагинов из их файловых путей (в подключенный сетевой диск), используя метод, показанный в другом потоке SO . Эти плагины предназначены для непрерывного выпуска, а это значит, что мне нужен постоянный доступ к их написанию. Текущий механизм блокирует файлы, поэтому я должен попросить всех закрыть программное обеспечение, чтобы я мог обновить файлы.

Вопрос:

Мне было интересно, было ли способ, возможно, используя метод, аналогичный описанному выше, импортировать файл из io.BytesIO объекта необработанного содержимого плагина (следовательно, разблокировать файл, чтобы я мог вносить изменения, как мне угодно).

В более общем плане:

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

Как я уже говорил в своем комментарии, я понимаю, что вы можете смонтировать виртуальный -filesystem на ОС Linux (которая могла бы решить мою проблему), хотя, к сожалению, я занимаюсь разработкой для Windows, и Microsoft никогда не сможет сделать вашу жизнь проще! : -)

Примечание:

Я не спрашиваю, где я могу скопировать эти файлы, чтобы импортировать их из локальной версии (например, temp, cache, et c). .).

Я понимаю, что это довольно специальный вопрос, поэтому любая помощь очень ценится

1 Ответ

0 голосов
/ 13 апреля 2020

Не будучи объектом io.BytesIO, как я изначально просил, я смог импортировать модуль из его источника после нахождения этой невероятно полезной статьи . Я не скопировал здесь код, так как он довольно большой, хотя я смог заставить его успешно импортировать виртуальный модуль.

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

Это не особенно красиво и определенно ломается некоторые Python рекомендации по стилю, так что я определенно открыт для улучшений!

source = """def hello():
    print("I don't want to say hi to the world")"""
name = "my_module"

glo = {}
exec(source, glo)

injector = DependencyInjector()
injector.provide(name, type(name, (), glo))
injector.install()

foo = __import__(name)
foo.hello()
...