如何在 Python 中最好地保存多个类实例?更新:如何腌制包含 osgeo.ogr 对象的类实例?
Posted
技术标签:
【中文标题】如何在 Python 中最好地保存多个类实例?更新:如何腌制包含 osgeo.ogr 对象的类实例?【英文标题】:How to best save a number of class instances in Python? Updated: how to pickle class instances that contains osgeo.ogr objects? 【发布时间】:2016-02-09 21:38:46 【问题描述】:我在 Python 持久性方面完全没有经验。 我尝试使用泡菜来存储一些代理以进行模拟。 我收到消息“TypeError:无法腌制 SwigPyObject 对象” 我换了货架。我得到了同样的错误。 这是我的代码。 我有 5 个对象列表,每个列表包含给定类的许多实例
to_store = [my_regions, my_agents, my_houses, my_families, my_firms]
我打开一个架子。
boxes = shelve.open((parameters.OUTPUT_PATH + "my_box"))
并尝试使用通用键从我的 5 个列表中保存每个实例
n = 0
for item in to_store:
for instance in item:
boxes[n] = instance
n += 1
然后我得到同样的泡菜错误 对不起,如果这听起来很简单。 但我以前从未使用过 python 存储(只是保存到 csv 并从中读取)。 谢谢。
这是我的代理课程:
类代理(对象):
# Class for agents. Citizens of the model
# Agents live in families, work in firms, consume
def __init__(self, id, gender, age, qualification, money, firm_id=None, family_id=None, utility=1,
address=None, distance=None, region_id=None):
self.id = id
self.gender = gender
self.age = age
self.month = fixed_seed.randrange(1, 13, 1)
self.qualification = qualification
self.money = money
self.firm_id = firm_id
self.family_id = family_id
self.utility = utility
self.address = address
self.distance = distance
self.region_id = region_id
也许问题是包含 GDAL/OSGEO 几何的类? 这是治理的代码。 region 是一个 shapefile ogr.object
class Govern(object):
def __init__(self, region, index=1, old_index=1, treasure=0, region_gdp=0, pop=0, total_commute=0):
# region is an OSGEO object that contains Fields and Geometry
self.region = region
# Make sure FIELD 0 is Name
self.name = self.region.GetField(0)
# Make sure FIELD 1 is IBGE CODE
self.id = self.region.GetField(1)
self.index = index
self.old_index = old_index
self.treasure = treasure
self.region_gdp = region_gdp
self.pop = pop
self.total_commute = total_commute
其他类类似。 家族和公司在其 init()
中有字典class Family(object):
def __init__(self, family_id, balance=0, household_id=None, region_id=None, house_price=0, address=None, house=None):
# Family is a set of agents store in a dictionary keyed by id
self.family_id = family_id
self.balance = balance
self.members =
这是我创建一些公司的方式,例如
def create_firm(num_firms, region, firm_id):
dummy_sector = []
for dummy_firm in range(num_firms):
address = get_random_point_in_polygon(region)
total_balance = fixed_seed.randrange(20, 400)
dummy_sector.append(firms.Firm(firm_id, address, total_balance, region.get_region_id()))
firm_id += 1
return dummy_sector
好的。经过所有的辩论,我想问题是从 OSGEO/GDAL 生成的对象。我使用: from osgeo import ogr
那么,问题应该改成:如何pickle包含osgeo.ogr对象的类实例?
【问题讨论】:
Agent
类中没有任何明显的内容可以解释 SwigPyObject
的来源。此外,如果我用random
替换fixed_seed
,我可以腌制它的一个实例:pickle.dumps(Agent(1, 'm', 22, 'qualification', 100))
有效。那么,fixed_seed
是什么?你能举例说明创建一个无法腌制的Agent
吗?
fixed_seed = random.Random (0)
只是为了通过不同的模块保持相同的种子。
好的,那么创建一个由于TypeError: can't pickle SwigPyObject objects
而无法腌制的Agent
的示例怎么样?必须有一些东西被传递给__init__()
,它引入了SwigPyObject
对象。
好的。我在问题中介绍了区域的 __init__() 。它确实包含一个 osgeo.ogr 对象(几何,ESRI 的 shapefile)。自治市的实际边界!感谢您的时间@mhawke
【参考方案1】:
在后台shelve
使用pickle
,所以如果你的对象不能被腌制,shelve
不能使用它们。
可能有一种方法可以存储来自每个对象的信息,以便以后可以通过对象实例化来重建该对象,但我们需要知道对象的详细信息,以及如何创建一个。
或者,可能,对象提供了转储它们的方法。
SwigPyObject
类的对象表明这些对象存在于 Python 外部的 C/C++ 库中。
如果可能,请提供课程的详细信息。
【讨论】:
我只写了一半几乎完全相同的答案;)swig.org/Doc3.0/SWIGDocumentation.html#Python_builtin_types 描述了 SwigPyObject,docs.python.org/3/library/pickle.html#pickle-inst 涵盖了腌制不可腌制的东西。 我的课程是业余的,没有任何复杂的方法。一些变量,一些方法。我认为 python 中的任何对象都可以轻松发送。我从未使用过 SwigPy。那么,有没有另一种方法来保存这些对象。问题是:使用 57000 个代理运行需要 3 个小时才能创建它们。我需要创建一次,每次运行时加载。我将检查 SwigPyObject 的文档。谢谢。 @B_Furtado:你说你没有使用 SWIG?SwigPyObject
s 来自哪里?您是否使用其他模块来创建对象?
我对 SwigPyObject 一无所知。但我确实有很多模块。每个类别至少有一个模块:代理商、公司、住户、地区等。它们都是类。例如,我实例化了一些 class.Agent 的对象,并将它们保存在我的列表中:my_agents。我是否必须在每个类中包含一个使它们的实例“可腌制”的方法?在过去的两个小时里,我一直在阅读它,所有的例子都是关于泡菜的一个简单的列表。我的对象很复杂。它们包含字典、几何。我只是想把它们存起来,以后再拿。谢谢。
@B_Furtado:如果没有关于这些对象的详细信息,很难提供帮助。这些模块是您编写的,还是第 3 方模块?如果是后者,它们是什么?您可以为这些类之一发布一个最小的示例类实现吗?以上是关于如何在 Python 中最好地保存多个类实例?更新:如何腌制包含 osgeo.ogr 对象的类实例?的主要内容,如果未能解决你的问题,请参考以下文章