修改参数的python函数

时间:2010-08-19 00:36:36

标签: python

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

函数add没有返回。我读到只有像list这样的可变对象才能进行更改。但为什么这个人省略了回报呢?有或没有回报是好的。为什么?这与C ++有很大的不同。

由于

4 个答案:

答案 0 :(得分:7)

  

但是为什么这个人省略了   返回?有或没有回报   很好。为什么?这是如此不同   来自C ++。

完全没有 - 它与所有意图和目的的C ++完全相同!只需在C ++版本中创建一个void add并将其参数a传递给std::vector<int>,通过引用 - 所有意图和目的,这就是这个Python {{1在C ++术语中看到了。

在Python术语中,当一个函数“完全落后”时,完全与在该点执行add时相同。在这种情况下(当函数总是以“从结尾处掉头”结束时)这是更好的风格,以避免冗余的return None语句(不要在多余的装饰中浪费像素和屏幕空间)这种)。

答案 1 :(得分:1)

add()变异a而不是重新绑定它,因此更改会显示在原始对象中。

答案 2 :(得分:1)

所有内容都是通过python中的引用传递的,但是整数,字符串等是不可变的,因此当您更改它时,您将创建一个绑定到局部变量的新变量,以便传递给函数的变量不会更改。 但是,列表和dicts是可变的 - 因此,如果您更改它们,则不会创建新对象,因此更改也会影响调用方范围内的变量。

答案 3 :(得分:0)

考虑以下C ++程序:

#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;
}

程序输出:

After add_val
1 2 3 
After add_ref
4 5 6 

vector传递给add_val()会导致原始vector保持不变,因为它是按值传递的。但是,将vector传递给add_ref()会导致原始vector内的值发生变化,因为它是通过引用传递的。

在Python 中,所有都通过引用传递。但是,很多内置类型(strtupleintfloat等)都是不可变的。这意味着您对这些类型执行的任何操作都会导致新变量在当前作用域中与新值绑定。对于可变类型(listdict等),最终完全与在C ++中通过引用传递参数的结果相同。