将一个python对象替换为另一个python对象
如何用另一个对象替换python对象 我有两个类,将一个python对象替换为另一个python对象,python,python-2.7,Python,Python 2.7,如何用另一个对象替换python对象 我有两个类,SimpleObject和FancyObject。我创建了一个SimpleObject,并对它进行了多次引用。现在我想创建一个FancyObject,并使所有这些引用指向新对象 a = SimpleObject() some_list.append(a) b = FancyObject() a=b不是我想要的,它只是改变了a指向的内容。我读到下面的内容会有用,但不会。我得到一个错误“属性不可写”: 我想要的是(pseudo-C)的等价物: 我知
SimpleObject
和FancyObject
。我创建了一个SimpleObject
,并对它进行了多次引用。现在我想创建一个FancyObject
,并使所有这些引用指向新对象
a = SimpleObject()
some_list.append(a)
b = FancyObject()
a=b
不是我想要的,它只是改变了a指向的内容。我读到下面的内容会有用,但不会。我得到一个错误“属性不可写”:
我想要的是(pseudo-C)的等价物:
我知道这很麻烦,但有没有办法做到这一点?没有办法。它会让你变异不可变的对象,并造成各种各样的肮脏
x = 1
y = (x,)
z = {x: 3}
magic_replace(x, [1])
# x is now a list!
# The contents of y have changed, and z now has an unhashable key.
x = 1 + 1
# Is x 2, or [1, 1], or something stranger?
您可以将该对象放在单独模块的全局命名空间中,然后在需要时对其进行修补
objstore.py
:
replaceable = object()
import objstore
b = object()
def isB():
return objstore.replaceable is b
if __name__ == '__main__':
print isB()#False
objstore.replaceable = b
print isB()#True
sample.py
:
replaceable = object()
import objstore
b = object()
def isB():
return objstore.replaceable is b
if __name__ == '__main__':
print isB()#False
objstore.replaceable = b
print isB()#True
p.S.依赖猴子补丁是设计不良的症状有一个功能replace\u all\u refs
,它可以替换对内存中对象的所有引用
文档中的一个示例:
>>> item = (100, 'one hundred')
>>> data = {item: True, 'itemdata': item}
>>>
>>> class Foobar(object):
... the_item = item
...
>>> def outer(datum):
... def inner():
... return ("Here is the datum:", datum,)
...
... return inner
...
>>> inner = outer(item)
>>>
>>> print item
(100, 'one hundred')
>>> print data
{'itemdata': (100, 'one hundred'), (100, 'one hundred'): True}
>>> print Foobar.the_item
(100, 'one hundred')
>>> print inner()
('Here is the datum:', (100, 'one hundred'))
调用replace_all_refs
>>> new = (101, 'one hundred and one')
>>> org_item = pyjack.replace_all_refs(item, new)
>>>
>>> print item
(101, 'one hundred and one')
>>> print data
{'itemdata': (101, 'one hundred and one'), (101, 'one hundred and one'): True}
>>> print Foobar.the_item
(101, 'one hundred and one')
>>> print inner()
('Here is the datum:', (101, 'one hundred and one'))
您有许多选择:
a = iter(b) # will blow up if not iterable
[x for x in b] # before change, was iterable, but between two lines, b was changed to an int.
另一个答案提到了实现选项3的方法。虽然它可能会起作用,但它有上面提到的所有问题。这可能只适用于调试和开发 利用列表等可变对象
a = [SimpleObject()]
some_list.append(a)
b = FancyObject()
a[0] = b
证明这是有效的:
class SimpleObject():
def Who(self):
print 'SimpleObject'
class FancyObject():
def Who(self):
print 'FancyObject'
>>> a = [SimpleObject()]
>>> a[0].Who()
SimpleObject
>>> some_list = []
>>> some_list.append(a)
>>> some_list[0][0].Who()
SimpleObject
>>> b = FancyObject()
>>> b.Who()
FancyObject
>>> a[0] = b
>>> some_list[0][0].Who()
FancyObject
嗯,
y
,z
的内容不会改变,因为它们指的是前面提到的x
。。唯一改变的是x
所指的内容。(如果我错了,请纠正我,因为我不知道C)。如果您只想更改名称x
所指的内容,那么x=您所要的就是它。如果你想用一个新对象神奇地替换x
所指的对象,那么这个对象必须在使用旧对象的任何地方都可见,包括dicts和tuples。@Schoolboy但这正是OP所要求的:不仅要替换x
,还要替换引用同一对象的所有其他名称。如果您没有意识到,在Python中1
是一个对象,在主Python实现中,所有使用值1
的东西都只是引用同一个对象。我应该补充一点,旧对象和新对象都有完全相同的接口,并且它们都是可变的(但它们在内部完全不同)。我可能会在所有列表和存储的属性中手动替换它们,或者创建一个代理对象(可能是最明智的事情,也是我应该做的事情)。但是我很好奇我是否可以偷偷地替换这个对象。@Marcin:Pyjack的replace\u all\u refs
是最好的选择。它在字符串上不能可靠地工作,我怀疑它在任何未经GC跟踪的情况下都能工作。如果它在存在任意C扩展的情况下是可靠的,我会大吃一惊。那么,您想更改a
存储位置中存储的数据吗?午饭后我会发布答案。@Schoolboy是的。基本上我把一个简单的对象放在了a中,当需要的时候,我想(懒洋洋地)把它升级到一个更复杂的对象b中。a和b有相同的接口,所以使用它们的代码应该能够处理这个问题。你应该在你的文章中包含更多关于你链接到什么的信息。