Проблема с использованием `shelf` в "__main__" по сравнению с импортированным модулем.Python

Программы на Python
Ответить Пред. темаСлед. тема
Anonymous
 Проблема с использованием `shelf` в "__main__" по сравнению с импортированным модулем.

Сообщение Anonymous »

Рассмотрим следующую программу (Python 3.10), которая состоит из двух файлов:
mymodule.py

Код: Выделить всё

import dataclasses
import shelve
from typing import Optional

# public api
# ----------

@dataclasses.dataclass
class SomeObject:
some_property: int = 0

def save_object (obj: SomeObject) -> None:
with shelve.open("theshelf", flag="c") as db:
db["object"] = obj

def load_object () -> Optional[SomeObject]:
with shelve.open("theshelf", flag="c") as db:
return db.get("object")

# tester
# ------

if __name__ == "__main__":
save_object(SomeObject())
obj = load_object()
myprogram.py

Код: Выделить всё

import mymodule

if __name__ == "__main__":
# this fails (see description below)
obj = mymodule.load_object()
Существует модуль mymodule.py, который содержит встроенную программу тестирования, которая запускается, если вы запускаете модуль напрямую. Это шаблон, который я обычно использую. Существует также «настоящая» программа myprogram.py. Это глупая программа, но она отражает мою проблему.
Проблема в следующем:
Если я запущу тестовый код, например python mymodule.py, все работает нормально, и файл полки записан.
Однако, если я сначала запущу тестовый код для сериализации SomeObject и затем запустите "настоящую" программу (

Код: Выделить всё

python myprogram.py
), я получаю следующую ошибку:

Код: Выделить всё

% python mymodule.py
% python myprogram.py

Traceback (most recent call last):
File "/opt/homebrew/Cellar/[email protected]/3.12.2_1/Frameworks/Python.framework/Versions/3.12/lib/python3.12/shelve.py", line 111, in __getitem__
value = self.cache[key]
~~~~~~~~~~^^^^^
KeyError: 'object'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
File "/Users/jason_pro2023/personal/shelf/myprogram.py", line 4, in 
obj = mymodule.load_object()
^^^^^^^^^^^^^^^^^^^^^^
File "/Users/jason_pro2023/personal/shelf/mymodule.py", line 18, in load_object
return db.get("object")
^^^^^^^^^^^^^^^^
File "/opt/homebrew/Cellar/[email protected]/3.12.2_1/Frameworks/Python.framework/Versions/3.12/lib/python3.12/shelve.py", line 106, in get
return self[key]
~~~~^^^^^
File "/opt/homebrew/Cellar/[email protected]/3.12.2_1/Frameworks/Python.framework/Versions/3.12/lib/python3.12/shelve.py", line 114, in __getitem__
value = Unpickler(f).load()
^^^^^^^^^^^^^^^^^^^
AttributeError: Can't get attribute 'SomeObject' on 
Я считаю, что когда я запускаю тестер, имя модуля — «__main__», и оно сохраняется на полке, когда SomeObject< /code> сериализуется. Тогда, если я запущу настоящую программу, имя модуля будет «mymodule» (а не «__main__»), и поэтому объект не сможет быть десериализован.
Мой вопрос: есть ли какие-нибудь как я могу избежать этого, но при этом продолжить встраивание тестового кода непосредственно в мои модули?
Я мог бы написать тестер как отдельное приложение, и, вероятно, именно это я и сделаю, если не нашел решения, но если есть способ обойти эту проблему, я бы предпочел оставить код в модуле.

Подробнее здесь: https://stackoverflow.com/questions/787 ... ted-module
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «Python»