为什么 python 列表在函数范围之外持续存在,而整数却没有?
Why do python lists persist outside function scope while integers don't?
Python 有效,这样我就可以在每次函数运行时就地更新 list
:
list_obj = list()
def increase_list_obj(list_obj, n):
list_obj.append(n)
print(list_obj)
for n in range(3):
increase_list_obj(list_obj, n)
print(list_obj)
OUTPUT:
[]
[0]
[0, 1]
[0, 1, 2]
根据 list
的持续存在方式,我希望我也可以在每次函数运行时就地更新 int
:
int_obj = 0
def increase_int_obj(int_obj):
int_obj += 1
print(int_obj)
for n in range(3):
increase_int_obj(int_obj)
print(int_obj)
OUTPUT:
0
0
0
0
EXPECTED:
0
1
2
3
为什么 int
更新的工作方式与 list
更新不同?
这两个对象的持久性和作用域规则有何不同?
(我并不是想建议两者应该表现相同,我很好奇为什么他们不这样做)
抢占有关如何更新 int
的答案:我知道您可以通过从函数返回值来更新 int
值:
int_obj = 0
def increase_int_obj_v2(int_obj):
int_obj += 1
return int_obj
print(int_obj)
for n in range(3):
int_obj = increase_int_obj_v2(int_obj)
print(int_obj)
OUTPUT:
0
1
2
3
谢谢!
如果函数内有赋值,则变量是局部的,否则它们是全局的:
i += 1
是一个作业 (i = i + 1
)!因此 i
是函数内的局部变量。
list_obj.append(n)
是突变!因此 list_obj
在封闭的命名空间中查找,它是全局命名空间。
旁注:+=
可以是可变类型的突变:list_obj += [n]
也是突变。
为了更好地理解,您需要了解一些概念
int
是不可变的,list
是可变的
可变和不可变对象列表
可变的内置类型对象是:
- 列表
- 套
- 词典
- 用户定义类
不可变的内置类型对象是:
- 数字(整数、有理数、浮点数、小数、复数和布尔值)
- 字符串
- 元组
- 冰雪奇缘套装
- User-Defined 类(完全由用户定义特性)
什么意思?
有关不可变和可变的更多信息,请阅读 this
一些对象通过引用传递给函数,一些对象通过值传递
(more)
Python 中的对象可以从任何范围修改。关于整数的事情是它们是不可变的对象,所以每当它们被修改时,它们都会为自己制作一个新副本,该副本只存在于它创建的范围内。
另一方面,列表与大多数其他 Python 对象一样,将在适当的位置进行修改,以允许进行更改,而不管当前范围如何。
这是一个使用自定义对象的示例。
class HoldInt:
def __init__(self, integer):
self.integer = integer
int_obj = HoldInt(0)
def modify_int():
int_obj.integer += 1
print(int_obj.integer)
modify_int()
print(int_obj.integer)
0
1
Python 有效,这样我就可以在每次函数运行时就地更新 list
:
list_obj = list()
def increase_list_obj(list_obj, n):
list_obj.append(n)
print(list_obj)
for n in range(3):
increase_list_obj(list_obj, n)
print(list_obj)
OUTPUT:
[]
[0]
[0, 1]
[0, 1, 2]
根据 list
的持续存在方式,我希望我也可以在每次函数运行时就地更新 int
:
int_obj = 0
def increase_int_obj(int_obj):
int_obj += 1
print(int_obj)
for n in range(3):
increase_int_obj(int_obj)
print(int_obj)
OUTPUT:
0
0
0
0
EXPECTED:
0
1
2
3
为什么 int
更新的工作方式与 list
更新不同?
这两个对象的持久性和作用域规则有何不同?
(我并不是想建议两者应该表现相同,我很好奇为什么他们不这样做)
抢占有关如何更新 int
的答案:我知道您可以通过从函数返回值来更新 int
值:
int_obj = 0
def increase_int_obj_v2(int_obj):
int_obj += 1
return int_obj
print(int_obj)
for n in range(3):
int_obj = increase_int_obj_v2(int_obj)
print(int_obj)
OUTPUT:
0
1
2
3
谢谢!
如果函数内有赋值,则变量是局部的,否则它们是全局的:
i += 1
是一个作业 (i = i + 1
)!因此 i
是函数内的局部变量。
list_obj.append(n)
是突变!因此 list_obj
在封闭的命名空间中查找,它是全局命名空间。
旁注:+=
可以是可变类型的突变:list_obj += [n]
也是突变。
为了更好地理解,您需要了解一些概念
int
是不可变的,list
是可变的
可变和不可变对象列表 可变的内置类型对象是:
- 列表
- 套
- 词典
- 用户定义类
不可变的内置类型对象是:
- 数字(整数、有理数、浮点数、小数、复数和布尔值)
- 字符串
- 元组
- 冰雪奇缘套装
- User-Defined 类(完全由用户定义特性)
什么意思?
有关不可变和可变的更多信息,请阅读 this
一些对象通过引用传递给函数,一些对象通过值传递 (more)
Python 中的对象可以从任何范围修改。关于整数的事情是它们是不可变的对象,所以每当它们被修改时,它们都会为自己制作一个新副本,该副本只存在于它创建的范围内。
另一方面,列表与大多数其他 Python 对象一样,将在适当的位置进行修改,以允许进行更改,而不管当前范围如何。
这是一个使用自定义对象的示例。
class HoldInt:
def __init__(self, integer):
self.integer = integer
int_obj = HoldInt(0)
def modify_int():
int_obj.integer += 1
print(int_obj.integer)
modify_int()
print(int_obj.integer)
0
1