Python-修改传递给函数的变量

Python-修改传递给函数的变量,python,reference,in-place,Python,Reference,In Place,如果我有一个函数f(x)和任何类型和范围的变量var,有没有办法修改var对f(var)的内部调用 这意味着函数f做了一些神奇的事情来获得对原始var的引用(如C++中的引用/指针),并修改原始var,用于任何类型的var(甚至int//code>float/str/字节) 不允许将var包装到dict或list或任何其他类中。因为大家都知道dict/list是通过引用传递的 也不允许从函数返回新值以重新分配变量 也不允许修改原始变量的范围(如使其成为全局变量) 事实上,不允许对函数调用方的代码

如果我有一个函数
f(x)
和任何类型和范围的变量
var
,有没有办法修改
var
f(var)
的内部调用

这意味着函数
f
做了一些神奇的事情来获得对原始
var
的引用(如
C++
中的引用/指针),并修改原始
var
,用于任何类型的
var
(甚至
int
//code>float/
str
/
字节

不允许将
var
包装到
dict
list
或任何其他类中。因为大家都知道dict/list是通过引用传递的

也不允许从函数返回新值以重新分配变量

也不允许修改原始变量的范围(如使其成为全局变量)

事实上,不允许对函数调用方的代码进行任何更改

该变量可以是任何想象的类型和范围,不应对其进行任何假设

这样下一个代码就可以工作了(这样的代码既可以放在另一个包装函数中,也可以放在全局范围内,这无关紧要):

如果需要解决任务,此函数可以执行任何复杂操作,如使用
inspect
模块

基本上,我需要以某种方式打破关于简单类型通过值传递的约定,即使是以某种非简单/神秘的方式实现这一点

我很确定这个任务可以通过标准逆向工程模块(如//)中的工具来解决


为了澄清我对这项任务的需求——目前,对于这项任务,我并没有尝试使用整洁的Python风格和方法来很好地编写代码,您可以想象,这项任务在未来是专门从事逆向工程/抗病毒药物/代码安全性/编译器实现的公司的面试问题。类似这样的任务还可以探索Python等语言的所有隐藏可能性。

正如@rcvaram所建议的那样,使用全局变量,如下所示

def magic_inplace_add(x, val):
    global var
    var = 333
global var
var = 111
magic_inplace_add(var, 222) # modifies int var by adding 222
print(var)

对于模块范围变量

import inspect
import re

def magic_inplace_add(var, val):
    '''
        Illustation of updating reference to var when function is called at module level (i.e. not nested)
    '''
    # Use inspect to get funcstion call syntax
    previous_frame = inspect.currentframe().f_back
    (filename, line_number, 
     function_name, lines, index) = inspect.getframeinfo(previous_frame)
    # lines contains call syntax
    # i.e. ['magic_inplace_add(x, 222)\n']
    args = re.findall("\w+", lines[0]) # get arguments of calling syntax i.e.  ('magic_inplace_add', 'x', 222)
    
    # Update variable in context of previous frame
    # i.e. args[1] == 'x' in example
    if args[1] in previous_frame.f_globals:
        # update variable from global
        previous_frame.f_globals.update({args[1]:var + val})
    elif args[1] in previous_frame.f_locals:
        # for nested function variable would be in f_locals
        # but this doesn't work in Python 3 this f_locals is a copy of actual locals in calling frame
        # see Martijn Pieters answer at
        # https://stackoverflow.com/questions/36678241/how-can-i-force-update-the-python-locals-dictionary-of-a-different-stack-frame
        previous_frame.f_locals.update({args[1]:var + val})  # this is what would be used for nested functions
     
示例

x = 111 # x module scope
y = 222 # y module scope
z = 333 # z module scope
magic_inplace_add(x, 222)
magic_inplace_add(y, 222)
magic_inplace_add(z, 222)
print(x)  # Output: 333
print(y)  # Output: 444
print(z)  # Output: 555

使用全局variables@rcvaram事实上,不允许以任何方式更改函数调用代码。您是否真的需要打破Python的基本规则,即不可变变量不能以这种方式修改?“已知dict/list是通过引用传递的”不知道,因为这是错误的。Python从不经过任何东西reference@Arty这根本不能回答我的问题。您所要求的并不是完全指定的,您不断地对Python的语义做出错误的陈述,试图解释您想要做什么,这使得它更加混乱。如果你想做一些非常粗糙的事情,那么你需要能够准确地解释你想做什么。我在我的问题中说过,不允许更改变量的类型或范围。事实上,不允许对函数的调用方代码进行任何修改。谢谢!向上投票。当测试代码在全局范围内时,至少对我有效。但奇怪的是,当测试代码在一个函数中不起作用时,局部变量dict不会改变,尽管magic func在模块级,@Arty——不奇怪——这是我对嵌套函数(即在另一个函数中)时不起作用的评论。问题是elif分支更新局部变量,而不是Python 3中的实际局部变量,正如我提供的链接所证明的那样。@DarryIG我认为您所说的func应该在模块/全局范围内,但正如我在前面的评论中对代码的链接一样,变量似乎也应该在模块/全局范围内?所以函数和变量都应该在全局范围内——这是代码运行的先决条件吗?但仍然是非常好的,至少有一个工作的解决方案已经张贴,我投了你的解决方案@顺便问一下,Python不允许修改前一帧的局部变量的原因是什么?是出于安全原因,防止我们做我们打算做的事情还是出于其他原因?@Arty——似乎这本可以在Python 2中使用,但Python 3的性能优化改变了行为,即。
x = 111 # x module scope
y = 222 # y module scope
z = 333 # z module scope
magic_inplace_add(x, 222)
magic_inplace_add(y, 222)
magic_inplace_add(z, 222)
print(x)  # Output: 333
print(y)  # Output: 444
print(z)  # Output: 555