鱼C论坛

 找回密码
 立即注册
查看: 2834|回复: 12

[已解决]关于全局变量 访问和修改的疑惑

[复制链接]
发表于 2020-2-20 12:38:42 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
result = []
def get_digits(x):

    if x:
        result.append(x % 10)

        get_digits(x // 10)
        result.sort()
       print(id(result))
        return result

print(get_digits(123))
print(id(result))

这里result是全局变量

我们在函数里对其进行了修改
按照原来的理解,函数可以访问但不能修改原全局变量 因此会在函数内部创建一个同名的新变量

为什么我这里打印两个变量的id 是同一个结果

result.append()
result.sort()
这种调用不算作修改全局变量吗
最佳答案
2020-2-20 13:42:32
0.
  1. x=[1,2,'3','sad']

  2. print(x,id(x))
  3. def change():
  4.     x=[2,'asd']
  5.     print(x,id(x))

  6. change()
  7. print(x,id(x))
复制代码


运行输出为
  1. [1, 2, '3', 'sad'] 4360925064
  2. [2, 'asd'] 4362353992
  3. [1, 2, '3', 'sad'] 4360925064
复制代码

1.
  1. x=[1,2,'3','sad']

  2. print(x,id(x))
  3. def change():
  4. #   x=[2,'asd']
  5.     x[1]=1
  6.     x[2]='asd'
  7.     x.pop()
  8.     x.pop()
  9.     print(x,id(x))

  10. change()
  11. print(x,id(x))
复制代码


运行结果为
  1. [1, 2, '3', 'sad'] 4555120520
  2. [1, 1] 4555120520
  3. [1, 1] 4555120520
复制代码

2.
我个人猜测的结论:当你用定义的方式在子函数中用列表,子函数会创建一个临时列表;当你在子函数只是对列表中的某个部分操作并不涉及定义的话,那么列表就在子函数中默认视为全局。因为整数,浮点数,字符串的定义以及赋值操作在python里是一样的,所以 在python里要额外声明这些变量是不是全局的。
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2020-2-20 12:42:19 | 显示全部楼层
在函数中可以通过全局变量的方法修改全局变量。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-2-20 13:13:53 | 显示全部楼层
zltzlt 发表于 2020-2-20 12:42
在函数中可以通过全局变量的方法修改全局变量。

你好 你的意思是 result.append()
相当于 global result 然后对其修改吗
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-2-20 13:32:07 | 显示全部楼层
retear 发表于 2020-2-20 13:13
你好 你的意思是 result.append()
相当于 global result 然后对其修改吗

不是,result.append() 是直接调用全局变量 result 的方法 append() 。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-2-20 13:42:32 | 显示全部楼层    本楼为最佳答案   
0.
  1. x=[1,2,'3','sad']

  2. print(x,id(x))
  3. def change():
  4.     x=[2,'asd']
  5.     print(x,id(x))

  6. change()
  7. print(x,id(x))
复制代码


运行输出为
  1. [1, 2, '3', 'sad'] 4360925064
  2. [2, 'asd'] 4362353992
  3. [1, 2, '3', 'sad'] 4360925064
复制代码

1.
  1. x=[1,2,'3','sad']

  2. print(x,id(x))
  3. def change():
  4. #   x=[2,'asd']
  5.     x[1]=1
  6.     x[2]='asd'
  7.     x.pop()
  8.     x.pop()
  9.     print(x,id(x))

  10. change()
  11. print(x,id(x))
复制代码


运行结果为
  1. [1, 2, '3', 'sad'] 4555120520
  2. [1, 1] 4555120520
  3. [1, 1] 4555120520
复制代码

2.
我个人猜测的结论:当你用定义的方式在子函数中用列表,子函数会创建一个临时列表;当你在子函数只是对列表中的某个部分操作并不涉及定义的话,那么列表就在子函数中默认视为全局。因为整数,浮点数,字符串的定义以及赋值操作在python里是一样的,所以 在python里要额外声明这些变量是不是全局的。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-2-20 13:54:36 | 显示全部楼层
非常有趣是
0.
  1. x=[1,2,'3','sad']

  2. print(x,id(x))
  3. def change():
  4.     global x
  5.     x=[2,'asd']
  6.     print(x,id(x))

  7. change()
  8. print(x,id(x))
复制代码

结果为
  1. [1, 2, '3', 'sad'] 4477439880
  2. [2, 'asd'] 4478868872
  3. [2, 'asd'] 4478868872
复制代码


1.
  1. x=1

  2. print(x,id(x))
  3. def change():
  4.     global x
  5.     x=2
  6.     print(x,id(x))

  7. change()
  8. print(x,id(x))
复制代码

结果为
  1. 1 4479364272
  2. 2 4479364304
  3. 2 4479364304
复制代码

2.
我个人猜测的结论:实际上,定义了global也并不是在原内存上操作而是,把这个全局标签贴在了别的内存上。下面例子更明显
  1. x=1
  2. y=x
  3. print(x,id(x))
  4. print(y,id(y))
  5. def change():
  6.     global x
  7.     x=2
  8.     print(x,id(x))
  9.     print(y,id(y))

  10. change()
  11. print(x,id(x))
  12. print(y,id(y))
复制代码

结果为
  1. 1 4515773616
  2. 1 4515773616
  3. 2 4515773648
  4. 1 4515773616
  5. 2 4515773648
  6. 1 4515773616
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-2-20 13:56:00 | 显示全部楼层

我明白了 谢谢
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-2-20 13:56:33 | 显示全部楼层
zltzlt 发表于 2020-2-20 13:32
不是,result.append() 是直接调用全局变量 result 的方法 append() 。

谢谢! 懂了
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-2-20 13:59:47 | 显示全部楼层

哇  这么看真的蛮有趣的,要注意的细节真的比想象中多
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-2-20 14:15:17 | 显示全部楼层
补充一下,你认为的 "函数可以访问但不能修改原全局变量 因此会在函数内部创建一个同名的新变量" 与 "result.append()
result.sort()
这种调用不算作修改全局变量吗"
这两句话里的 "修改" 是有两种意思的, 一个是值的改变,一个是内存地址的改变。
对于一个变量来说,只有 内存地址 改变了,才能在真正意义上被称作修改。
而你这道题,你需要去了解一下 "python的可变类型与不可变类型",如果你去了解并且弄明白了以后,上面的答案与例子会更加清晰明了。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-2-20 16:45:24 | 显示全部楼层
°蓝鲤歌蓝 发表于 2020-2-20 14:15
补充一下,你认为的 "函数可以访问但不能修改原全局变量 因此会在函数内部创建一个同名的新变量" 与 "resul ...

好的  非常感谢 我会去看看的!
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-2-20 16:51:10 | 显示全部楼层

楼下有人提到了可变类型和不可变类型

建议你也看看

http://blog.itpub.net/31544234/viewspace-2157363/
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-2-20 19:10:31 | 显示全部楼层
retear 发表于 2020-2-20 16:51
楼下有人提到了可变类型和不可变类型

建议你也看看

谢谢
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2026-3-2 15:24

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表