使用Python,有没有办法存储对引用的引用,以便我可以在另一个上下文中更改引用引用的内容?例如,假设我有以下类:
class Foo:
def __init__(self):
self.standalone = 3
self.lst = [4, 5, 6]
我想创建类似于以下内容的内容:
class Reassigner:
def __init__(self, target):
self.target = target
def reassign(self, value):
# not sure what to do here, but reassigns the reference given by target to value
这样下面的代码
f = Foo()
rStandalone = Reassigner(f.standalone) # presumably this syntax might change
rIndex = Reassigner(f.lst[1])
rStandalone.reassign(7)
rIndex.reassign(9)
会导致f.standalone
等于7
且f.lst
等于[4, 9, 6]
。
基本上,这将是指向指针的类似物。
答案 0 :(得分:6)
简而言之,这是不可能的。完全没有。最接近的等价物是存储对要重新分配其成员/项目的对象的引用,加上属性名称/索引/键,然后使用setattr
/ setitem
。但是,这会产生完全不同的语法,您必须区分这两者:
class AttributeReassigner:
def __init__(self, obj, attr):
# use your imagination
def reassign(self, val):
setattr(self.obj, self.attr, val)
class ItemReassigner:
def __init__(self, obj, key):
# use your imagination
def reassign(self, val):
self.obj[self.key] = val
f = Foo()
rStandalone = AttributeReassigner(f, 'standalone')
rIndex = ItemReassigner(f.lst, 1)
rStandalone.reassign(7)
rIndex.reassign(9)
我实际上使用的东西非常相似,但有效的用例很少。
对于全局/模块成员,您可以使用模块对象或globals()
,具体取决于您是在模块内部还是在模块外部。根本没有局部变量的等价物 - locals()
的结果不能用于更改本地人,它只对检查有用。
我实际上使用的东西非常相似,但有效的使用案例却很少。
答案 1 :(得分:2)
简单回答:你不能。
class Reassigner:
def __init__(self, target):
self.reassign = target
f = Foo()
rIndex = Reassigner(lambda value: f.lst.__setitem__(1, value))
rStandalone = Reassigner(lambda value: setattr(f, 'strandalone', value))
rF = Reassigner(lambda value: locals().__setitem__('f', value)
答案 2 :(得分:1)
如果你需要推迟任务;您可以使用functools.partial
(或只是lambda
):
from functools import partial
set_standalone = partial(setattr, f, "standalone")
set_item = partial(f.lst.__setitem__, 1)
set_standalone(7)
set_item(9)
如果reassign
是唯一的操作;你不需要新课。
函数是Python中的一等公民:您可以将它们分配给变量,存储在列表中,作为参数传递等。
答案 3 :(得分:0)
这适用于容器对象的内容。如果你不介意为你的变量添加一个间接级别(无论如何你在C指针到指针的情况下都需要),你可以:
class Container(object):
def __init__(self, val):
self.val = val
class Foo(object):
def __init__(self, target):
self.standalone = Container(3)
self.lst = [Container(4), Container(5), Container(6)]
你根本不需要reassigner对象。
Class Reassigner(object):
def __init__(self, target):
self.target = target
def reassign(self, value):
self.target.val = value