在枚举中pickle对象?



我正在做一个工作项目,我在酸洗方面遇到了问题。

下面是我要做的事情的简化:

import pickle
from enum import Enum

class SiteInformation:
def __init__(self, name, location):
self.name = name
self.location = location
# Would actually be doing a number of calcs with name and location and storing
# as members.
self.time_zone = 'UTC'

class Site(Enum):
GN = SiteInformation('North Site', 'Location String1')
GS = SiteInformation('South Site', 'Location String2')

if __name__ == '__main__':
print('Pickling...')
with open('site_test', 'wb') as f:
pickle.dump(Site.GN, f)
pickle.dump(Site.GS, f)
print('Unpickling...')
with open('site_test', 'rb') as f:
data = pickle.load(f)
print(data)

当我运行这个时,它在解pickle过程中失败:

Traceback (most recent call last):
File "/Users/seb/Development/Scheduler/scripts/pickle_test.py", line 27, in <module>
data = pickle.load(f)
File "/Applications/Anaconda/anaconda3/envs/Scheduler/lib/python3.10/enum.py", line 385, in __call__
return cls.__new__(cls, value)
File "/Applications/Anaconda/anaconda3/envs/Scheduler/lib/python3.10/enum.py", line 710, in __new__
raise ve_exc
ValueError: <__main__.SiteInformation object at 0x7fd77007ed40> is not a valid Site

我认为这与SiteInformation中的__init__调用有关,但我不太确定如何解决这个问题,因为我对酸洗的经验很少。我曾尝试在SiteInformation中实现__repr__方法,但这只不过是使ValueError更具可读性。

任何帮助都将是非常感激的。

在Python 3.11中,这将像编写的那样工作。在早期的python中,您需要添加__eq__(如果您希望set()dict()支持1,则需要添加__hash__)以使具有相同值的SiteInformation的不同实例能够比较相等:

class SiteInformation:
def __init__(self, name, location):
self.name = name
self.location = location
# Would actually be doing a number of calcs with name and location and storing
# as members.
self.time_zone = 'UTC'
def __eq__(self, other):
return self.name == other.name and self.location == other.location

注意:__eq__仅供示例使用。一个"真正"__eq__看起来像:

def __eq__(self, other):
if not isinstance(other, self.__class__):
return NotImplemented
return self.name == other.name and self.location == other.location

__hash__可能看起来像:

def __hash__(self):
return hash(self.name + self.location)

1:__hash__需要对象在set()中,或者在dict()中用作键。

这似乎已经解决了这个问题,并使代码库相当干净(基于EnumPython文档中的Planet示例):

class Site(Enum):
GN = ('North Site', 'Location String1')
GS = ('South Site', 'Location String2')

def __init__(self, site_name: str, location: str):
self.site_name = site_name
self.location = location
self.time_zone = 'UTC'
# Insert other member calculations here

相关内容

  • 没有找到相关文章

最新更新