在Python中如何使用函数返回val作为左val ?

时间:2022-04-07 23:51:19

I want to make the below c code work in Python, how can I make it?

我想让下面的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;
}

When I write a low level function such s goo I want to use the pointer returned by high level user-defined function foo.

当我编写这样一个低级函数时,我想使用高级用户定义函数foo返回的指针。

It is really easy in c and I want to make it in Python, How? Thanks!!

这在c中很简单,我想用Python来做,怎么做?谢谢! !

3 个解决方案

#1


1  

It would be good to ask why you want this. If I saw code like this in C, I would strongly discourage the author from writing this: it looks like an intentionally way to obfuscate.

问一下你为什么想要这个。如果我在C中看到这样的代码,我强烈建议作者不要这样写:它看起来像是故意混淆的一种方式。

f's sole purpose seems to be to allow mutation on a. In that case, the function signature is weird. Why not:

f的唯一目的似乎是允许a发生突变,在这种情况下,函数签名很奇怪。为什么不:

typedef void (*func)(int, int);

which takes in the index as well as the value you're trying to set? In this case, we can even give this signature a good name, a "setter".

它包含索引和要设置的值?在这种情况下,我们甚至可以给这个签名一个好名字,一个“setter”。

typedef void (*setter)(int, int);

With this, the C code is simple and direct,

有了它,C代码简单而直接,

void foo(int i, int val) { a[i] = val; }

void goo(setter f) {
  int i = 0;
  for(; i < 2; ++i) f(i, 7);
}

and the Python translation of this is also straightforward.

Python对它的翻译也很简单。

If you truly needed something like this, just capture the idea of mutation in something callable, and return that. That's really what a pointer is, right? For example:

如果你真的需要这样的东西,那就在一些可调用的东西中捕捉突变的想法,然后返回它。这就是指针,对吧?例如:

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 pointer isn't a pointer because it's physically represented by a "star" operator. It's a pointer because we can refer and mutate it. We can do that with just plain functions:

指针不是指针,因为它在物理上由“星型”运算符表示。它是一个指针,因为我们可以引用并改变它。我们可以用简单的函数来做:

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

If we wanted to make it prettier, I suppose we could use classes.

如果我们想让它更漂亮,我想我们可以用类。

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

But again, I would not just blindly use this: I'd rather see real code and see what you're trying to do.

但是,我不会盲目地使用它:我宁愿看到真正的代码,看看您正在尝试做什么。

#2


1  

Like others, I really don't see why you'd want this. But you could return a function that changes something.

和其他人一样,我真的不明白你为什么要这样。但是你可以返回一个改变某些东西的函数。

Here's a translation of your code:

以下是你的代码的翻译:

# 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)

#3


0  

There are no pointers in Python, or arrays for that matter. Rather than fill in a list created someplace else, the usual Python idiom is to return a modified copy of the list.

在Python中没有指针,也没有数组。通常的Python习惯用法是返回修改后的列表副本,而不是填入其他地方创建的列表。

However, Python does let you define your own object types, and overload what the operators mean. So, while there is no unary * to overload in Python, you could overload what p[x] means, and p[0] means the same thing as *p in C.

但是,Python允许您定义自己的对象类型,并重载操作符的含义。所以,虽然在Python中没有一元*可以重载,但是可以重载p[x]的意思,而p[0]的意思和C中的*p是一样的。

Read here about what you can do with Python classes. "New-style" classes are the best choice in Python 2.x and become the only choice in Python 3. http://docs.python.org/2/reference/datamodel.html

请阅读本文,了解如何使用Python类。“新式”类是Python 2中最好的选择。成为Python 3中唯一的选择。http://docs.python.org/2/reference/datamodel.html

As for passing a function to a Python function, just pass the name, without parentheses:

对于将函数传递给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] )

As you can see, library functions pass just as well as user defined ones.

如您所见,库函数和用户定义的函数一样可以传递。

#1


1  

It would be good to ask why you want this. If I saw code like this in C, I would strongly discourage the author from writing this: it looks like an intentionally way to obfuscate.

问一下你为什么想要这个。如果我在C中看到这样的代码,我强烈建议作者不要这样写:它看起来像是故意混淆的一种方式。

f's sole purpose seems to be to allow mutation on a. In that case, the function signature is weird. Why not:

f的唯一目的似乎是允许a发生突变,在这种情况下,函数签名很奇怪。为什么不:

typedef void (*func)(int, int);

which takes in the index as well as the value you're trying to set? In this case, we can even give this signature a good name, a "setter".

它包含索引和要设置的值?在这种情况下,我们甚至可以给这个签名一个好名字,一个“setter”。

typedef void (*setter)(int, int);

With this, the C code is simple and direct,

有了它,C代码简单而直接,

void foo(int i, int val) { a[i] = val; }

void goo(setter f) {
  int i = 0;
  for(; i < 2; ++i) f(i, 7);
}

and the Python translation of this is also straightforward.

Python对它的翻译也很简单。

If you truly needed something like this, just capture the idea of mutation in something callable, and return that. That's really what a pointer is, right? For example:

如果你真的需要这样的东西,那就在一些可调用的东西中捕捉突变的想法,然后返回它。这就是指针,对吧?例如:

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 pointer isn't a pointer because it's physically represented by a "star" operator. It's a pointer because we can refer and mutate it. We can do that with just plain functions:

指针不是指针,因为它在物理上由“星型”运算符表示。它是一个指针,因为我们可以引用并改变它。我们可以用简单的函数来做:

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

If we wanted to make it prettier, I suppose we could use classes.

如果我们想让它更漂亮,我想我们可以用类。

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

But again, I would not just blindly use this: I'd rather see real code and see what you're trying to do.

但是,我不会盲目地使用它:我宁愿看到真正的代码,看看您正在尝试做什么。

#2


1  

Like others, I really don't see why you'd want this. But you could return a function that changes something.

和其他人一样,我真的不明白你为什么要这样。但是你可以返回一个改变某些东西的函数。

Here's a translation of your code:

以下是你的代码的翻译:

# 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)

#3


0  

There are no pointers in Python, or arrays for that matter. Rather than fill in a list created someplace else, the usual Python idiom is to return a modified copy of the list.

在Python中没有指针,也没有数组。通常的Python习惯用法是返回修改后的列表副本,而不是填入其他地方创建的列表。

However, Python does let you define your own object types, and overload what the operators mean. So, while there is no unary * to overload in Python, you could overload what p[x] means, and p[0] means the same thing as *p in C.

但是,Python允许您定义自己的对象类型,并重载操作符的含义。所以,虽然在Python中没有一元*可以重载,但是可以重载p[x]的意思,而p[0]的意思和C中的*p是一样的。

Read here about what you can do with Python classes. "New-style" classes are the best choice in Python 2.x and become the only choice in Python 3. http://docs.python.org/2/reference/datamodel.html

请阅读本文,了解如何使用Python类。“新式”类是Python 2中最好的选择。成为Python 3中唯一的选择。http://docs.python.org/2/reference/datamodel.html

As for passing a function to a Python function, just pass the name, without parentheses:

对于将函数传递给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] )

As you can see, library functions pass just as well as user defined ones.

如您所见,库函数和用户定义的函数一样可以传递。