我想让下面的c代码在Python中运行,我该怎么做呢?
// low level
typedef int* (*func)(int);
// high level
int a[2];
// high level
int* foo(int i) { return &a[i]; }
// low level
void goo(func f) {
int i = 0;
for(; i < 2; ++i) *f(i) = 7;
}
int main(void)
{
goo(foo);
return 0;
}
当我写一个低级函数时,我想使用高级用户定义函数foo返回的指针。
在c中真的很容易,我想用Python制作它,怎么样? 谢谢!
答案 0 :(得分:1)
最好问为什么你想要这个。如果我在C中看到这样的代码,我会强烈反对作者写这个:它看起来像是一种有意混淆的方式。
f
的唯一目的似乎是允许在a
上进行变异。在这种情况下,函数签名很奇怪。为什么不:
typedef void (*func)(int, int);
它接收索引以及您尝试设置的值?在这种情况下,我们甚至可以给这个签名一个好名字,一个“setter”。
typedef void (*setter)(int, int);
有了这个,C代码简单直接,
void foo(int i, int val) { a[i] = val; }
void goo(setter f) {
int i = 0;
for(; i < 2; ++i) f(i, 7);
}
并且Python的翻译也很简单。
如果你确实需要这样的东西,只需捕捉可调用的东西中的变异的想法,然后返回。这真的是一个指针,对吗?例如:
a = [0, 0]
def foo(i):
def mutate(v):
a[i] = v
return mutate
def goo(f):
for i in range(2):
f(i)(7)
if __name__ == '__main__':
goo(foo)
print a
指针不是指针,因为它实际上由“星形”运算符表示。它是一个指针,因为我们可以引用和改变它。我们可以用简单的函数来做到这一点:
a = [4, 17]
def foo(i):
def ref():
return a[i]
def mutate(v):
a[i] = v
return { 'ref' : ref, 'mutate' : mutate }
def goo(f):
for i in range(2):
ptr = f(i)
print "at", i, "I see", ptr['ref']()
ptr['mutate'](7)
if __name__ == '__main__':
goo(foo)
print a
如果我们想让它更漂亮,我想我们可以使用类。
a = [4, 17]
def foo(i):
class Ptr(object):
def __init__(self): pass
def ref(self):
return a[i]
def set(self, v):
a[i] = v
return Ptr()
def goo(f):
for i in range(2):
ptr = f(i)
print "at", i, "I see", ptr.ref()
ptr.set(7)
if __name__ == '__main__':
goo(foo)
print a
但同样,我不会盲目地使用它:我宁愿看到真实的代码,看看你想要做什么。
答案 1 :(得分:1)
和其他人一样,我真的不明白你为什么要这样做。但是你可以返回一个改变某些东西的函数。
以下是您的代码的翻译:
# high level
a [ 0, 0 ]
# high level
def foo(i):
def change(n): a[i] = n
return change
# low level
def goo(f):
for i in range(2):
f(i)(7)
goo(foo)
答案 2 :(得分:0)
Python中没有指针或数组。而不是填写在其他地方创建的列表,通常的Python习惯用法是返回列表的修改副本。
但是,Python确实允许您定义自己的对象类型,并重载运算符的含义。因此,虽然在Python中没有一元*重载,但你可以重载p [x]的意思,而p [0]意味着与C中的* p相同。
在这里阅读有关Python类可以做什么的内容。 “新风格”类是Python 2.x中的最佳选择,并成为Python 3中的唯一选择。 http://docs.python.org/2/reference/datamodel.html
至于将函数传递给Python函数,只需传递名称,不带括号:
import math
def f1(x):
return 2*x + 1
def sumf( func, vals ):
return sum( func(x) for x in vals );
print sumf( f1, (1, 2, 3) )
print sumf( math.cos, [0, math.pi/2, math.pi] )
如您所见,库函数的传递与用户定义的函数一样。