当前位置:  开发笔记 > 编程语言 > 正文

在Python中模拟指针

如何解决《在Python中模拟指针》经验,为你挑选了4个好方法。

我正在尝试将内部语言(ihl)交叉编译为Python.

ihl的一个特性是指针和引用,其行为与您对C或C++的期望相同.

例如,你可以这样做:

a = [1,2];  // a has an array 
b = &a;     // b points to a
*b = 2;     // derefernce b to store 2 in a
print(a);   // outputs 2
print(*b);   // outputs 2

有没有办法在Python中复制此功能.

我应该指出,我认为我困惑了一些人.我不想要Python中的指针.我只是想从Python专家那里得到一个感觉,我应该生成什么样的Python来模拟我上面展示的情况

我的Python不是最好的,但到目前为止,我的探索还没有产生任何有希望的东西:(

我应该指出,我们正在寻求从我们的ihl转向更常用的语言,因此如果有人可以提出可能更适合的另一种语言,我们就不会真正与Python绑定.



1> ephemient..:

这可以明确地完成.

class ref:
    def __init__(self, obj): self.obj = obj
    def get(self):    return self.obj
    def set(self, obj):      self.obj = obj

a = ref([1, 2])
b = a
print a.get()  # => [1, 2]
print b.get()  # => [1, 2]

b.set(2)
print a.get()  # => 2
print b.get()  # => 2


您可能不想使用名称"ref",因为它与weakref引用的名称相同.也许是"ptr"之类的东西.但是,这是一个明智的实施.
您可以交替覆盖`__call__`来实现获取和设置,这更类似于weakref的行为方式.
请注意,这在使用不可变对象(如int或字符串)时才有意义.对于可变对象a = Something(); B = A; 完全够了.即使使用不可变对象,它也毫无意义......

2> Stephan202..:

您可能希望从C++角度阅读Python变量名的语义.底线:所有变量都是引用.

更重要的是,不要考虑变量,而是考虑可以命名的对象.


当然它有变量; Python中的变量是一个命名对象.说"Python没有变量"只会让事情变得不必要.

3> Glenn Maynar..:

如果您正在编译类似C语言,请说:

func()
{
    var a = 1;
    var *b = &a;
    *b = 2;
    assert(a == 2);
}

进入Python,然后所有"Python中的所有东西都是参考"的东西是用词不当.

确实,Python中的所有内容都是一个引用,但许多核心类型(整数,字符串)不可变的事实在许多情况下都会有效地解除这一点.在Python中没有直接的方法来实现上述内容.

现在,您可以间接地执行此操作:对于任何不可变类型,将其包装为可变类型.Ephemient的解决方案有效,但我经常这样做:

a = [1]
b = a
b[0] = 2
assert a[0] == 2

(我这样做是为了解决Python在2.xa中缺少"非本地"几次.)

这意味着更多的开销:每个不可变类型(或者每个类型,如果你不试图区分)突然创建一个列表(或另一个容器对象),所以你会显着增加变量的开销.单独地,它并不是很多,但是当应用于整个代码库时它会加起来.

您可以通过仅包装不可变类型来减少这种情况,但是您需要跟踪输出中的哪些变量被包装,哪些不包含,因此您可以使用"a"或"a [0]"访问该值适当.它可能会毛茸茸的.

至于这是否是一个好主意 - 这取决于你为什么这样做.如果你只是想要运行VM,我倾向于拒绝.如果您希望能够从Python调用现有语言,我建议您使用现有的VM并为其创建Python绑定,以便您可以从Python访问和调用它.



4> Mark Mikofsk..:

几乎完全像我投票的流行 答案,你可以使用Python的内置属性函数.它将ref在ephemient的答案中做类似于类的操作,除了现在,您只需调用您在类定义中指定为属性的实例的属性,而不是强制使用getset方法来访问ref实例.从Python文档(除了我将C更改为ptr):

class ptr(object):
    def __init__(self):
        self._x = None
    def getx(self):
        return self._x
    def setx(self, value):
        self._x = value
    def delx(self):
        del self._x
    x = property(getx, setx, delx, "I'm the 'x' property.")

这两种方法都像C指针一样工作,没有求助global.例如,如果你有一个带指针的函数:

def do_stuff_with_pointer(pointer, property, value):
    setattr(pointer, property, value)

例如

a_ref = ptr()      # make pointer
a_ref.x = [1, 2]   # a_ref pointer has an array [1, 2]
b_ref = a_ref      # b_ref points to a_ref
# pass ``ptr`` instance to function that changes its content
do_stuff_with_pointer(b_ref, 'x', 3)
print a_ref.x      # outputs 3
print b_ref.x      # outputs 3

另一个完全疯狂的选择是使用Python的ctypes.试试这个:

from ctypes import *
a = py_object([1,2]) # a has an array 
b = a                # b points to a
b.value = 2          # derefernce b to store 2 in a
print a.value        # outputs 2
print b.value        # outputs 2

或者如果你想得到真正的幻想

from ctypes import *
a = py_object([1,2])   # a has an array 
b = pointer(a)         # b points to a
b.contents.value = 2   # derefernce b to store 2 in a
print a.value          # outputs 2
print b.contents.value # outputs 2

这更像是OP的原始要求.疯!

推荐阅读
拾味湖
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有