List元素Python中的指针

时间:2016-04-28 09:55:25

标签: python

我的问题来自this page,而我想为列表元素创建一个指针(类似的东西)。元素是一个原始值(字符串)所以我必须像该页面那样创建一个FooWrapper类。

我知道通过设置__repr__可以直接访问此值。

class FooWrapper(object):
    def __init__(self, value):
         self.value = value
    def __repr__(self):
         return repr(self.value)


>>> bar=FooWrapper('ABC')
>>> bar
'ABC'
>>> bar=FooWrapper(3)
>>> bar
3

现在我可以将它用作字符串的引用:

>>> L=[3,5,6,9]
>>> L[1]=FooWrapper('ABC')
>>> L
[3,'ABC',6,9]
>>> this=L[1]
>>> this.value='BCD'
>>> print(L)
[3,'BCD',6,9]

所以现在我对列表元素this有一个类似指针的L[1]

然而,由于我必须使用this.value='BCD'更改其值,因此仍然不方便。虽然存在__repr__方法使this直接返回this.value,但有没有类似的方法让this='BCD'this.value='BCD'?我知道这会改变绑定规则..但无论如何,这有可能吗?

如果列表元素指针有更好的解决方案,我也很感激。

提前谢谢你:)

3 个答案:

答案 0 :(得分:2)

我不确定你想要做什么,但你可以这样做:

class FooWrapper(object):
    def __init__(self, value):
         self.value = value
    def __repr__(self):
         return 'FooWrapper(' + repr(self.value) + ')'
    def __str__(self):
        return str(self.value)
    def __call__(self,value):
        self.value = value

在这里,我摆脱了使用__repr__来隐藏FooWrapper的想法,因为我认为向程序员隐瞒REPL中发生的事情是个坏主意。相反 - 我使用了__str__,这样当您打印对象时,您将打印包装的值。 __call__作为默认方法运行,它不会改变=的含义,但有点像你想要的那样:

>>> vals = [1,2,3]
>>> vals[1] = FooWrapper("Bob")
>>> vals
[1, FooWrapper('Bob'), 3]
>>> for x in vals: print(x)

1
Bob
3
>>> this = vals[1]
>>> this(10)
>>> vals
[1, FooWrapper(10), 3]

但是,我认为引用this作为指针是误导性的。它只是一个包装器对象,并且几乎肯定会使处理包装对象变得不方便。

On Edit:以下是列表的指针。它允许您创建类似指针对象的东西,其中__call__用于取消引用指针(当没有传递参数时)或改变列表(当值传递给__call__时)。它还实现了一个带有环绕的p++形式(pp)(虽然环绕部分当然可以被删除):

class ListPointer(object):
    def __init__(self, myList,i=0):
         self.myList = myList
         self.i = i % len(self.myList)

    def __repr__(self):
         return 'ListPointer(' + repr(self.myList) + ',' + str(self.i) + ')'

    def __str__(self):
        return str(self.myList[self.i])

    def __call__(self,*value):
        if len(value) == 0:
            return self.myList[self.i]
        else:
            self.myList[self.i] = value[0]

    def pp(self):
        self.i = (self.i + 1) % len(self.myList)

像这样使用:

>>> vals = ['a','b','c']
>>> this = ListPointer(vals)
>>> this()
'a'
>>> this('d')
>>> vals
['d', 'b', 'c']
>>> this.pp()
>>> this()
'b'
>>> print(this)
b

我认为这是一种更透明的方式来获取像列表指针一样的东西。它不要求指向的东西被包裹在任何东西中。

答案 1 :(得分:0)

__repr__方法可以获得它想要的字符串。我们说它是return repr(self.value) + 'here'。如果你说this = '4here',应该受到什么影响?应self.value分配给4还是4here?如果this有另一个名为key__repr__的属性return repr(self.key) + repr(self.value),该怎么办?完成this = '4here'后,是否会将self.key分配给整个字符串,将self.value分配给整个字符串,或将self.key分配给4和{{1}到self.value?如果字符串完全由方法组成怎么办?如果它显示herereturn 'here'应该做什么?

简而言之,你不能。

答案 2 :(得分:0)

根据John Coleman的想法自我回答:

class ListPointer(object):
    def __init__(self,list,index):
          self.value=list[index]
          list[index]=self
    def __repr__(self):
          return self.value
    def __call__(self,value):
          self.value=value

>>> foo=[2,3,4,5]
>>> this=ListPointer(foo,2)
>>> this
4
>>> foo
[2,3,4,5]
>>> this('ABC')
>>> foo
[2,3,'ABC',5]
>>> type(foo(2))
<class '__main__.ListPointer'>

ListPointer对象接受列表和索引,将list[index]存储在self.value中,然后用self替换list元素。类似地,也可以实现pp方法,同时应该恢复前一个元素,并用self对象替换下一个元素。通过直接引用foo[2],也可以得到这个对象,这就是我想要的。 (也许这应该被称为参考而不是指针..)