【问题标题】:Send by ref/by ptr in python? [duplicate]在 python 中通过 ref/ptr 发送? [复制]
【发布时间】:2013-10-16 16:45:34
【问题描述】:

我需要帮助-我尝试通过 ref/by ptr 向 c++ 中的方法发送值 我该怎么做?

举例:

 def test(x):
    x=3    

 x=2
 test(x)
 print(x)

在这种情况下 x 是测试方法中的局部变量,不会改变“原始”X 那么如何更改“原始”X? 谢谢

【问题讨论】:

  • 不要尝试用 Python 编写其他语言(或者,实际上,用其他语言编写 Python)。
  • @BurhanKhalid 可变对象和不可变对象之间也没有区别(就参数传递而言)。一切都以相同的方式传递——例如,不可变对象是复制的——唯一的区别是用不可变对象观察这一点稍微困难一些。

标签: python python-3.x


【解决方案1】:

在某些方面,Python 中的所有调用都是通过引用调用的。事实上,所有变量在某种意义上都是引用。但是某些类型,例如您示例中的int,无法更改。

例如,list,您正在寻找的功能是微不足道的:

def change_it(some_list):
    some_list.append("world")

foo = ["hello"]
change_it(foo)
print(foo)  # prints ['hello', 'world']

但是,请注意,重新分配 参数 变量 some_list 不会更改调用上下文中的值。

不过,如果您问这个问题,您可能希望使用一个函数设置两个或三个变量。在这种情况下,您正在寻找这样的东西:

def foo_bar(x, y, z):
    return 2*x, 3*y, 4*z

x = 3
y = 4
z = 5
x, y, z = foo_bar(x, y, z)
print(y)  # prints 12

当然,您可以在 Python 中做任何事情,但这并不意味着您应该这样做。按照电视节目 Mythbusters 的风格,这里有一些东西可以满足您的需求

import inspect

def foo(bar):
    frame = inspect.currentframe()
    outer = inspect.getouterframes(frame)[1][0]
    outer.f_locals[bar] = 2 * outer.f_locals[bar]

a = 15
foo("a")
print(a) # prints 30

甚至更糟:

import inspect
import re

def foo(bar):
    # get the current call stack
    my_stack = inspect.stack()
    # get the outer frame object off of the stack
    outer = my_stack[1][0]
    # get the calling line of code; see the inspect module documentation
    #   only works if the call is not split across multiple lines of code
    calling_line = my_stack[1][4][0]
    # get this function's name
    my_name = my_stack[0][3]
    # do a regular expression search for the function call in traditional form
    #   and extract the name of the first parameter
    m = re.search(my_name + "\s*\(\s*(\w+)\s*\)", calling_line)
    if m:
        # finally, set the variable in the outer context
        outer.f_locals[m.group(1)] = 2 * outer.f_locals[m.group(1)]
    else:
        raise TypeError("Non-traditional function call.  Why don't you just"
                        " give up on pass-by-reference already?")

# now this works like you would expect
a = 15
foo(a)
print(a)

# but then this doesn't work:
baz = foo_bar
baz(a)  #  raises TypeError

# and this *really*, disastrously doesn't work
a, b = 15, 20
foo_bar, baz = str, foo_bar
baz(b) and foo_bar(a)
print(a, b)  # prints 30, 20

拜托,拜托拜托,不要这样做。我把它放在这里只是为了激发读者去研究 Python 中一些比较晦涩的部分。

【讨论】:

  • 不通过引用调用,调用为引用对象。默认情况下所有参数都是通过引用传递的。
  • 好点。现在修复它
  • 您使用f_locals 的示例在一般情况下不起作用。只要给定的名称是快速本地名称(因为它适用于大多数函数的本地范围内的变量),那么f_locals dict 将不包含该值,它位于f_localsplus 中,普通python 无法访问该名称。没有合理的方法可以将数据从 f_locals 推送到 f_localsplus(ctypes 除外)。
  • @dequestarmappartialsetattr 很高兴知道。我并不打算将它作为一种实际可用的方法,而是一种炫耀inspect 模块的方式。不过谢谢。我学到了一些东西
【解决方案2】:

据我所知,这在 Python 中不存在(尽管如果将可变对象传递给函数也会发生类似的事情)。你会这样做

def test():
    global x
    x = 3

test()

def test(x):
    return 3

x = test(x)

第二个更受欢迎。

【讨论】:

    猜你喜欢
    • 2021-10-08
    • 2013-09-30
    • 1970-01-01
    • 2017-12-08
    • 2020-11-25
    • 2017-07-12
    • 2019-08-24
    • 2018-07-29
    • 1970-01-01
    相关资源
    最近更新 更多