我有一个带有几个字典的对象,其中包含其他对象以及id和对象列表。
每次更改应用于其中一个词组时,生成此对象的n个副本的最pythonic方法是什么?
例如:
class B(object):
pass
class A(object):
def __init__(self):
d = {1: B(), 2: B(), 3: B()}
a = A()
b = [(1, B()), (2, B())]
我想生成两个a
的副本,每个副本有一个不同的B实例。如果可能,我想避免使用深度复制。
编辑,因为我被要求更具体:
我正在运行n次计算,每次更改某个子模块的一个参数。我想避免在内存中保存n个子模块副本,因为它是一个非常大的对象,我想避免重新初始化模拟的其他部分。因此,我希望有一个初始化的基础对象,我想在其上做一些小的修改,从而使用不同的参数运行计算n次。
答案 0 :(得分:0)
A().d
永远不会更改,因此创建副本或创建新实例没有区别。
因此,要创建一个A()
的新实例,其中包含B()
的新的单独实例,只需创建一个新实例:
second_a = A()
可以直接在此新实例上创建实例之间的任何变体。如果创建这样的对象很昂贵,请使用缓存策略以避免重复计算。
答案 1 :(得分:0)
我认为import_fresh_module
可以为您提供帮助,根据文档中的说明和您的需求说明。但我不能多说,不够熟练。
答案 2 :(得分:0)
您的示例未将d
分配给任何内容,因此当__init__
返回时它将丢失。但是评论表明你希望它是A
的实例属性;我假设那就是你想要的。我会实现一个copy
方法来复制你想要的东西。例如,我相信这符合您指定的标准,至少对于您提供的示例代码:
class B(object):
pass
class A(object):
def __init__(self, d=None):
if d is not None:
self.d = d
else:
self.d = {1: B(), 2: B(), 3: B()}
def copy(self, updates=None):
a = type(self)(self.d.copy())
if updates is not None:
a.d.update(updates)
return a
a = A()
b = [(1, B()), (2, B())]
a2 = a.copy(b)
答案 3 :(得分:0)
你可以在这里做一个单独模式的形式,它将缓存'昂贵'位并允许你通过再次调用它来设置变量位来设置不同的参数:
class BigAssThang(object):
instances={}
def __new__(cls, ID, *args):
if ID in cls.instances:
return cls.instances[ID]
else:
# do somthing really big, expensive and immutable...
cls.instances[ID]=super(BigAssThang, cls).__new__(cls)
return cls.instances[ID]
def __init__(self, ID, thing1=None, thing2=None, etc=None):
# set the parameters...
# ANY PREVIOUS INSTANCE's PARAMS ARE WIPED OUT!!!
self.ID=ID
self.thing1=thing1
self.thing2=thing2
self.etc=etc
def __repr__(self):
return 'id={} ID: {} thing1: {} thing2: {} etc: {}'.format(
id(self), self.ID, self.thing1, self.thing2, self.etc)
使用:
>>> a=BigAssThang(1,'thing 1', {}, [])
>>> a.etc.append(2)
>>> a
id=4481412944 ID: 1 thing1: thing 1 thing2: {} etc: [2]
>>> b=BigAssThang(1,'thing 1', {}, [])
>>> b
id=4481412944 ID: 1 thing1: thing 1 thing2: {} etc: []
>>> a
id=4481412944 ID: 1 thing1: thing 1 thing2: {} etc: []
>>> c=BigAssThang(2,'thing 1', {'a':22}, [1,2,3])
>>> c
id=4481413072 ID: 2 thing1: thing 1 thing2: {'a': 22} etc: [1, 2, 3]
>>> b
id=4481412944 ID: 1 thing1: thing 1 thing2: {} etc: []
知道将参数设置为b
后,将其设置为a
。它由ID
的{{1}}参数控制 - 而不是Python变量名。