python 值传递

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/gang950502/article/details/76146018

深拷贝和浅拷贝

普通变量赋值特性

```python
    >>> a = '1'
    >>> b = a
    >>> b = '2'
    >>> print a, b
    1 2
```

* 普通变量在相互赋值中都指向原地址
* 普通变量在赋值时如果原地址上还有其他引用则会新开辟出一块内存,原地址上数据不做修改

列表的引用和赋值特性

```python
    >>> a = [1,3,5]                                 
    >>> b = a                                      
    >>> b.append(7)                                  
    >>> print a, b           
    [1, 3, 5, 7] [1, 3, 5, 7]                       
    >>> b = 3                                       
    >>> print a , b          
    [1, 3, 5, 7] 3   
```        

* 与普通变量一样,默认都指向变量的原始内存
* 与普通变量一样,在引用被重新赋值时发现原始内存上还有引用,则开出一块新内存用于存放变量,原始内存不修改

函数入参是形参还是实参?

```python
>>> def func1(int_i):
...     int_i = int_i + 1
...     print int_i
>>> a = 5
>>> func1(a)
6
>>> print a
5
```  
  • 普通变量引用传值
    python
    >>> def func2(int_i):
    ... int_i.append('7')
    ... print int_i
    >>> a = ['1','2','3']
    >>> func2(a)
    ['1', '2', '3', '7']
    >>> print a
    ['1', '2', '3', '7']
  • 列表也是引用传值

线程入参传的是实参还是形参

测试程序 test_thread.py
“`python

# -*- coding: utf-8 -*-

import threading
import time

class c_test(threading.Thread):
    def __init__(self,seq,stnum):
        threading.Thread.__init__(self)
        self.seq = seq
        self.stnum = stnum
    def run(self):
        for i in range(self.stnum,self.stnum+10):
            self.seq.append(i)
            print self.seq
            time.sleep(1)
if __name__ == "__main__":
    A = []
    B = c_test(A,1)
    C=  c_test(A,20)
    B.start()
    time.sleep(0.5)
    C.start()
    time.sleep(12)
```

测试结果
“`

>>> execfile('test_thread.py')
[1]
[1, 20]
[1, 20, 2]
[1, 20, 2, 21]
[1, 20, 2, 21, 3]
[1, 20, 2, 21, 3, 22]
[1, 20, 2, 21, 3, 22, 4]
[1, 20, 2, 21, 3, 22, 4, 23]
[1, 20, 2, 21, 3, 22, 4, 23, 5]
[1, 20, 2, 21, 3, 22, 4, 23, 5, 24]
[1, 20, 2, 21, 3, 22, 4, 23, 5, 24, 6]
[1, 20, 2, 21, 3, 22, 4, 23, 5, 24, 6, 25]
[1, 20, 2, 21, 3, 22, 4, 23, 5, 24, 6, 25, 7]
[1, 20, 2, 21, 3, 22, 4, 23, 5, 24, 6, 25, 7, 26]
[1, 20, 2, 21, 3, 22, 4, 23, 5, 24, 6, 25, 7, 26, 8]
[1, 20, 2, 21, 3, 22, 4, 23, 5, 24, 6, 25, 7, 26, 8, 27]
[1, 20, 2, 21, 3, 22, 4, 23, 5, 24, 6, 25, 7, 26, 8, 27, 9]
[1, 20, 2, 21, 3, 22, 4, 23, 5, 24, 6, 25, 7, 26, 8, 27, 9, 28]
[1, 20, 2, 21, 3, 22, 4, 23, 5, 24, 6, 25, 7, 26, 8, 27, 9, 28, 10]
[1, 20, 2, 21, 3, 22, 4, 23, 5, 24, 6, 25, 7, 26, 8, 27, 9, 28, 10, 29]
```

* 线程传入的也是实参,即对象的引用。

列表的截断赋值会引发深拷贝

```python

>>> A = [1,2,3,4]
>>> B = A[:]
>>> C=  A[1,3]
>>> print A,B,C
[1, 2, 3, 4] [1, 2, 3, 4] [2]
>>> B[0] = 5
>>> C[0] = 6
>>> print A,B,C
[1, 2, 3, 4] [5, 2, 3, 4] [6]
```

测试结论

* python 中默认的值传递方式都以实参的方式传递,即参数的引用,但与C++的引用不同的是引用可以被重新赋值。
* 若需要在多个调用内使用不同的变量副本则需要进行深拷贝才可以。

猜你喜欢

转载自blog.csdn.net/gang950502/article/details/76146018