如何在 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? SwigPyObjects 来自哪里?您是否使用其他模块来创建对象? 我对 SwigPyObject 一无所知。但我确实有很多模块。每个类别至少有一个模块:代理商、公司、住户、地区等。它们都是类。例如,我实例化了一些 class.Agent 的对象,并将它们保存在我的列表中:my_agents。我是否必须在每个类中包含一个使它们的实例“可腌制”的方法?在过去的两个小时里,我一直在阅读它,所有的例子都是关于泡菜的一个简单的列表。我的对象很复杂。它们包含字典、几何。我只是想把它们存起来,以后再拿。谢谢。 @B_Furtado:如果没有关于这些对象的详细信息,很难提供帮助。这些模块是您编写的,还是第 3 方模块?如果是后者,它们是什么?您可以为这些类之一发布一个最小的示例类实现吗?

以上是关于如何在 Python 中最好地保存多个类实例?更新:如何腌制包含 osgeo.ogr 对象的类实例?的主要内容,如果未能解决你的问题,请参考以下文章

Scala 类型关键字:如何最好地在多个类中使用它

在 Python 中使用类实例树

如何最好地在 NHibernate 中检索和更新这些对象?

同时安装多个 Python 发行版会遇到啥问题,以及如何最好地避免这些问题? [复制]

js单例模式

设计问题:如何最好地使用构图