python-引用地址问题

  • 1、a,b = 0,0 与 a = b = 0
  • 2、函数形参的默认构造 def test(a=0) 与def test(a=list())
  • 2.1 测试 def test(a=0)
  • 2.2 测试 def test(a=list())
  • 2.3 测试 def test(a="")
  • 3、列表(list)原因分析
  • 4、整形(int)原因分析
  • 5、python中可变数据类型与不可变数据类型


1、a,b = 0,0 与 a = b = 0

>>>a = 'ABC'
>>>b = a
>>>a = 'XYZ'
>>>print(b)
ABC

# 巧用
# 当a与b变量内容需要互换的时候,直接可以复制即可。
>>>a, b = b, a

最后一行打印出变量b的内容到底是’ABC’呢还是’XYZ’?如果从数学意义上理解,就会错误地得出b和a相同,也应该是’XYZ’,但实际上b的值是’ABC’,让我们一行一行地执行代码,就可以看到到底发生了什么事:

执行a = ‘ABC’,解释器创建了字符串’ABC’和变量a,并把a指向’ABC’:

python ABC 鸭子 python中abc>xyz_Python


执行b = a,解释器创建了变量b,并把b指向a指向的字符串’ABC’:

python ABC 鸭子 python中abc>xyz_Code_02


执行a = ‘XYZ’,解释器创建了字符串’XYZ’,并把a的指向改为’XYZ’,但b并没有更改:

python ABC 鸭子 python中abc>xyz_Code_03


所以,最后打印变量b的结果自然是’ABC’了。

2、函数形参的默认构造 def test(a=0) 与def test(a=list())

第6章-3 列表或元组的数字元素求和 (20 分)

def test(a=0)和def test(a=list()) 是函数声明,都是在参数里面定义了一个变量a,不同点是递归使用。如果递归的时候a(int)是局部变量,每次递归都会创建新的变量;递归是a(list)时是伪全局,只有最外围递归结束,才被撤销。

2.1 测试 def test(a=0)

def test(a, b=0):
    b+=a
    if b < 5:
        test(a)
    return b

print(test(1))

死循环,跳不出递归,控制台信息:

Traceback (most recent call last):
  File "E:\Python_Code\测试.py", line 34, in <module>
    print(test(1))
  File "E:\Python_Code\测试.py", line 31, in test
    test(a)
  File "E:\Python_Code\测试.py", line 31, in test
    test(a)
  File "E:\Python_Code\测试.py", line 31, in test
    test(a)
  [Previous line repeated 995 more times]
  File "E:\Python_Code\测试.py", line 30, in test
    if b < 5:
RecursionError: maximum recursion depth exceeded in comparison

2.2 测试 def test(a=list())

def test(a, b=list()):
    b.append(a)
    if len(b) < 5:
        test(a)
    return b
    
print(test(1))

可以跳出递归,且打印结果为:

[1, 1, 1, 1, 1]

2.3 测试 def test(a="")

def test(a, b=""):
    b+=a
    if len(b) < 5:
        test(a)
    return b

print(test("1"))

死循环,跳出递归,控制台信息:

Traceback (most recent call last):
  File "E:\Python_Code\测试.py", line 34, in <module>
    print(test("1"))
  File "E:\Python_Code\测试.py", line 31, in test
    test(a)
  File "E:\Python_Code\测试.py", line 31, in test
    test(a)
  File "E:\Python_Code\测试.py", line 31, in test
    test(a)
  [Previous line repeated 995 more times]
  File "E:\Python_Code\测试.py", line 30, in test
    if len(b) < 5:
RecursionError: maximum recursion depth exceeded while calling a Python object

进程已结束,退出代码为 1

3、列表(list)原因分析

def fun(a = list()):
    print(id(a))
    a.append(1)
    print(id(a))

b = list()
print(id(b))
fun(b)
print(id(b))

# 2223860558912
# 2223860558912
# 2223860558912
# 2223860558912

从打印信息中可以看出,都是用的同一个地址,因此再次调用或改变值的时候不会创建新的地址。

4、整形(int)原因分析

def fun(a):
    print(id(a))
    a+=1
    print(id(a))

b = 10
print(id(b))
fun(b)
print(id(b))

# 140716787968080
# 140716787968080
# 140716787968112
# 140716787968080

从打印信息中可以看出,都是用的同一个地址,因此再次调用不会创建新的地址,但是如果改变值则会创建新的地址。

5、python中可变数据类型与不可变数据类型

  • 可变类型:在id(内存地址)不变的情况下,value(值)可以变,则称为可变类型
  • 不可变类型:value(值)一旦改变,id(内存地址)也改变,则称为不可变类型(id变,意味着创建了新的内存空间)

(红色为可变类型)
1、字符串 str
2、布尔类型 bool
3、整数 int
4、浮点数 float
5、数字 (int和float)
6、元组 tuple
7、列表 list
8、集合 list
9、字典 dict list
10、日期 date