为了账号安全,请及时绑定邮箱和手机立即绑定

在Python中模拟指针

在Python中模拟指针

万千封印 2019-11-27 13:20:43
我正在尝试将内部语言(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 aprint(a);   // outputs 2print(*b);   // outputs 2有没有办法在Python中复制此功能。我应该指出,我认为我已经混淆了一些人。我不要Python中的指针。我只是想向那里的Python专家了解一下,我应该生成什么Python以模拟上面显示的情况我的Python不是最好的Python,但到目前为止,我的探索还没有产生任何有希望的东西:(我应该指出,我们正在寻求从ihl转向更通用的语言,因此,如果有人可以提出另一种更合适的语言,我们就不会真正依赖于Python。
查看完整描述

3 回答

?
尚方宝剑之说

TA贡献1788条经验 获得超4个赞

可以明确地做到这一点。


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


查看完整回答
反对 回复 2019-11-27
?
叮当猫咪

TA贡献1776条经验 获得超12个赞

如果要编译类似C的语言,请说:


func()

{

    var a = 1;

    var *b = &a;

    *b = 2;

    assert(a == 2);

}

进入Python,那么所有“ Python的一切都是参考”的东西都是用词不当。


的确,Python中的所有内容都是引用,但是许多核心类型(int,字符串)是不可变的,这一事实在许多情况下实际上都无法解决。没有直接的方法可以在Python中实现上述功能。


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


a = [1]

b = a

b[0] = 2

assert a[0] == 2

(我这样做是为了解决Python在2.xa中缺少“非本地”的问题。)


这意味着更多的开销:每个不可变类型(或每个类型,如果您不想区分的话)都会突然创建一个列表(或另一个容器对象),因此您在增加变量的开销。单独来说,它并不多,但是当应用于整个代码库时,它会累加起来。


您可以通过只包装不可变类型来减少这种情况,但是随后您需要跟踪输出中包装了哪些变量,哪些没有包装,因此可以使用“ a”或“ a [0]”访问值适当地。可能会长毛。


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


查看完整回答
反对 回复 2019-11-27
?
哆啦的时光机

TA贡献1779条经验 获得超6个赞

几乎就像我投票赞成的短暂 答案一样,您可以使用Python的内置属性函数。它将执行与refephemient答案中的类几乎类似的操作,只是现在,您不必调用被迫使用get和set方法来访问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的原始请求。疯!


查看完整回答
反对 回复 2019-11-27
  • 3 回答
  • 0 关注
  • 437 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号