传参不规范,亲人两行泪
Python中的参数传递并非传值也非传引用,传的是对象的引用。
这是一个结论,如果想要知道更多的细节,请阅读《编写高质量代码:改善Python程序的91个建议》的第31条建议。
在Python里面,俺们接触到的所有数据类型都是对象,包括常数和字符串。
假设有下面代码:
a = 'ichxx'
def foo(x):
x = x[::-1]
print(x)
foo(a)
print(a)
当a传递给x时,它对应的内存模型是这样的
当切片时,产生了新的字符串,此时内存模型变为:
现在,a与x就没有关联了,自然对x的更改就不会反馈到a了
那么,什么样的改变会反馈到实参呢?
在函数中,对可变对象的修改会反馈到对象本身,而对不可变对象的修改则不会
可以把变量名理解成标签,对象理解成商品,俺们通过标签去寻找商品。当可变对象修改时,俺们通过标签寻找的东西也就相应改变。而不可变对象不可变,所以俺们只能把标签撕下来贴到别的商品上面,这样俺们也能实现“改变寻找到的东西”的目的,但原来的商品有没有变呢?没有。
最后附上引起俺思考这个问题的一段代码(最短寻道算法的实现)
def SCAN(arr=None):
if not arr:
raise NoArrayError
new_arr = sorted(arr) # 原先是写arr.sort(),这样会改变原来的arr,而arr是全局共用的。这会导致别的调度算法测试时的序列改变。
pos = 0
movement = 0
if cur < new_arr[0]:
new_arr.append(0, cur)
FCFS(new_arr)
elif cur > new_arr[-1]:
new_arr.append(cur)
FCFS(new_arr[::-1])
else:
for i in range(len(new_arr)-1):
if new_arr[i] < cur < new_arr[i+1]:
pos = i+1
movement = abs(cur - new_arr[i+1])
break
movement += sum([abs(x-y) for x, y in zip(new_arr[pos:-1], new_arr[pos+1:])])
movement += abs(new_arr[-1] - new_arr[pos-1])
movement += sum([abs(x-y) for x, y in zip(new_arr[:pos-1], new_arr[1:pos])])
return movement