开发者

python function that modifies parameters

开发者 https://www.devze.com 2023-01-11 23:41 出处:网络
def add(a,b): for i in range(len(a)): a[i] = a[i] + b def main(): amounts = [100,200] rate = 1 add(amounts,rate)
def add(a,b):
    for i in range(len(a)):
        a[i] = a[i] + b

def main():
    amounts = [100,200]
    rate = 1
    add(amounts,rate)
    print amounts

main()

The function add does not have a return. I read开发者_Python百科 that changes are available to only mutable objects like list. But why did the person omits the return? Either with or without return is fine. Why? This is so different from C++.

Thanks


But why did the person omits the return? Either with or without return is fine. Why? This is so different from C++.

Not at all - it's identical to C++ to all intent and purposes! Just make, in the C++ version, a void add and pass its argument a, say a std::vector<int>, by reference -- to all intents and purposes, this is what this Python add is doing, seen in C++ terms.

In Python terms, when a function "falls off the end" that's exactly the same as if it executed return None at that point. It's better style in such cases (when a function always ends by "falling off the end") to avoid the redundant return None statement (don't waste pixels and screen space in redundant ornamentation of this kind).


add() mutates a instead of rebinding it, so the change shows up in the original object.


Everything is passed by reference in python, but integers, strings etc. are immutable so when you change it you create a new one which is bound to the local variable so the variable passed to the function isn't changed. Lists and dicts are, however, mutable - so if you change them no new object is created and due to this the change also affects the variable in the caller's scope.


Consider the following C++ program:

#include <vector>
#include <iostream>

void add_val(std::vector<int> addTo, int addThis)
{
    for(std::vector<int>::iterator it = addTo.begin(); it!=addTo.end(); ++it)
    {
        *it += addThis;
    }
}

void add_ref(std::vector<int>& addTo, int addThis)
{
    for(std::vector<int>::iterator it = addTo.begin(); it!=addTo.end(); ++it)
    {
        *it += addThis;
    }
}

int main()
{
    std::vector<int> myVector;

    myVector.push_back(1);
    myVector.push_back(2);
    myVector.push_back(3);

    add_val(myVector, 3);

    std::cout<<"After add_val"<<std::endl;
    for (std::vector<int>::iterator it = myVector.begin(); it!=myVector.end(); ++it)
    {
        std::cout<<*it<<" ";
    }

    std::cout<<std::endl;

    add_ref(myVector, 3);

    std::cout<<"After add_ref"<<std::endl;
    for (std::vector<int>::iterator it = myVector.begin(); it!=myVector.end(); ++it)
    {
        std::cout<<*it<<" ";
    }
    std::cout<<std::endl;

    return 0;
}

The program outputs:

After add_val
1 2 3 
After add_ref
4 5 6 

Passing the vector to add_val() results in the original vector remaining unchanged, since it is passed by value. Passing the vector to add_ref() however, causes the values inside the original vector to change, since it's passed by reference.

In Python everything is passed by reference. However, a lot of the builtin types (str, tuple, int, float, etc.) are immutable. This means that any operation you perform on these types results in a new variable being bound in the current scope with the new value. For mutable types (list, dict, etc.), you end up with exactly the same result as passing a parameter by reference in C++.

0

精彩评论

暂无评论...
验证码 换一张
取 消