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’:
执行b = a,解释器创建了变量b,并把b指向a指向的字符串’ABC’:
执行a = ‘XYZ’,解释器创建了字符串’XYZ’,并把a的指向改为’XYZ’,但b并没有更改:
所以,最后打印变量b的结果自然是’ABC’了。
2、函数形参的默认构造 def test(a=0) 与def test(a=list())
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