6

使用 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等于7f.lst等于[4, 9, 6]

本质上,这类似于指针对指针。

4

4 回答 4

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()不能用于可靠地更改局部变量,它仅对检查有用。

我实际上使用了非常相似的东西,但有效的用例很少而且相差甚远。

于 2013-05-09T20:14:22.483 回答
2

简单的回答:你不能。
复杂的答案:您可以使用 lambdas。有点。

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)
于 2013-05-09T20:18:46.773 回答
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)

Ifreassign是唯一的操作;你不需要一个新的类。函数是 Python 中的一等公民:您可以将它们分配给变量、存储在列表中、作为参数传递等。

于 2013-05-09T21:26:14.877 回答
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
于 2013-05-09T20:40:48.807 回答