我正在尝试将内部语言(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绑定.
这可以明确地完成.
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
您可能希望从C++角度阅读Python变量名的语义.底线:所有变量都是引用.
更重要的是,不要考虑变量,而是考虑可以命名的对象.
如果您正在编译类似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访问和调用它.
几乎完全像我投票的流行 答案,你可以使用Python的内置属性函数.它将ref
在ephemient的答案中做类似于类的操作,除了现在,您只需调用您在类定义中指定为属性的实例的属性,而不是强制使用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的原始要求.疯!