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 ++有很大的不同。
由于
答案 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 中,所有都通过引用传递。但是,很多内置类型(str
,tuple
,int
,float
等)都是不可变的。这意味着您对这些类型执行的任何操作都会导致新变量在当前作用域中与新值绑定。对于可变类型(list
,dict
等),最终完全与在C ++中通过引用传递参数的结果相同。