Следующий код использует менеджер контекста для хранения и загрузки переменных в файлы. Однако очень неприятно иметь свойство value
того, что loaded.value
менеджер контекста (loaded.value
). я бы хотел
LoadedValue
loaded
) равным сохраненному значению.Решение любой из этих проблем будет оценено.
import os
import pickle
from contextlib import contextmanager
class LoadedValue:
def __init__(self, value):
self.value = value
def __str__(self):
return "<LoadedValue: {}>".format(self.value)
@contextmanager
def load_manager(load_file="file.pkl"):
with open(load_file, "rb") as f:
loaded_object = LoadedValue(pickle.load(f))
try:
yield loaded_object
finally:
with open(load_file, "wb+") as f:
pickle.dump(loaded_object.value, f)
if __name__ == "__main__":
filename = "test.pkl"
with open(filename, "wb+") as f:
pickle.dump(7, f)
with load_manager(filename) as loaded:
print(loaded) # >>> <LoadedValue: 7>
loaded.value = 5 # this is what I have to do
# loaded = 5 # this is what I want to do
with load_manager(filename) as loaded:
print(loaded) # >>> <LoadedValue: 5>
Примечание. Первоначально он был размещен в CodeReview, но я решил опубликовать его здесь, чтобы получить ответы, и оставить его в CodeReview, чтобы улучшить код другими способами.
нет, в python нет способа переопределить оператор присваивания, поэтому вы не можете делать с loaded = 5
(Вы можете переопределить другие вещи, чтобы это могло работать)
__call__
для разрешения loaded(5)
__lshift__
чтобы разрешить loaded << 5
__ior__
чтобы разрешить loaded |= 5
(однако будьте предупреждены ваши коллеги, или будущие коллеги могут никогда не простить вас)
Кроме того, вещи, которые происходят в области with XXXX as Y:
блоком with XXXX as Y:
блока with XXXX as Y:
(обычно) не доступны для метода, создающего контекст, если только эта область ранее не была доступна для места, предоставляющего область (то есть для глобального пространства имен и т.д.)
+=
или что-то, если вы хотите ... или вы можете сделать что-то вроде__call__
(5), определив метод __call__ вашего класса LoadedValue