Send by ref/by ptr in python?

This question already has an answer here:

  • How do I pass a variable by reference? 23 answers

  • In some ways, all calls in Python are called with references. In fact, all variables are references in a sense. But some types, like int from your example, cannot be changed.

    In the case of, say, a list , the functionality you're looking for is trivial:

    def change_it(some_list):
        some_list.append("world")
    
    foo = ["hello"]
    change_it(foo)
    print(foo)  # prints ['hello', 'world']
    

    Note, however, that reassigning the parameter variable some_list does not change the value in the calling context.

    If you're asking this question, though, you're probably looking to do something like set two or three variables using one function. In that case, you're looking for something like this:

    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
    

    Of course, you can do anything in Python, but that doesn't mean you should. In the fashion of the TV show Mythbusters, here's something that does what you're looking for

    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
    

    or even worse:

    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
    

    Please, please, please , don't do this. I only put it in here to inspire the reader to look into some of the more obscure parts of Python.


    As far as I am aware, this doesn't exist in Python (although a similar thing occurs if you pass mutable objects to a function). You would do either

    def test():
        global x
        x = 3
    
    test()
    

    or

    def test(x):
        return 3
    
    x = test(x)
    

    The second of these is much preferred.

    链接地址: http://www.djcxy.com/p/20842.html

    上一篇: 变量名称作为函数参数?

    下一篇: 在python中通过ref / by ptr发送?