Sisyphus
71天前
880
举报

新手请教一些python问题

请问左图错误的原因是x未定义吗?为什么不是沿用第1行的x=1从而输出2呢?

可以理解为global x用于所def的函数内x首次出现的位置,并且视作在该行定义了x嘛?

遇到这类编程问题(不属于直接问题目的做法的这种)有办法自行搜索解决嘛?如果有求详细操作...

此外,求一个稳妥的vsc安装教程,当初对着网上的教程装上后发现有的程序在IDLE里写完后能跑出来,在vsc里却一直报错,估计是自己vsc安装时操作出了问题。谢谢!

(这些问题我都有尝试解决,现在假期去问TA感觉不太合适。敬请龙友别回答“你不会百度吗?”这类,万分感谢!)


热评 (1)


刘洋
71天前
查看回复(1)

节前摸鱼答一发。
这个问题不是所谓百度&Google&SOF能解决的,因为初学者缺少提问的经验(没错,提问也是门学问),几乎不可能找到正确的相关知识。
编程语言里面有个概念叫scope,常翻译为作用域。变量说白了就是个名字,作用域决定了哪些部分的代码可以获取到这个名字。
先看左边的代码,你在函数里执行x=x+1,这相当于告诉计算机:定义一个变量x,并且它的值是x+1。在“定义变量x”这一步,计算机创造了一个local variable x,这个x和外界的global variable x是不同的(本质上是内存地址不同),只是名字一样(这个现象叫shadowing)。所以在第二步自增的时候,在evaluate x+1时,计算机发现local x根本就没有声明&赋值过,就会报错。
右边的global关键词告诉计算机,这里我要用全局变量x,于是函数里就能获取到x的值,并进行自增操作。
不过在实践中,global是强烈不建议使用的。因为它会导致代码难以阅读和debug。
总结一下,这个case难以理解的原因在于:
1. Python is very simple, so even a single expression could involve a great set of complicated memory manipulations. Python简单易学的背后是极高的复杂度,因为语言实现者把复杂度屏蔽在了底层。于是,一个简单的=符号其实包含了内存分配、变量声明、赋值等一系列操作(Python不区分声明和赋值,新人更难以理解)。
2. 初学者缺乏底层知识。scope和shadowing的概念涉及到内存堆栈和函数生命周期的关系,在缺乏这些知识的情况下, 对这类现象不必过于深究,只需要懂一些表面即可。
其实我一直很反对无脑让新手百度的行为,因为其实“懂得如何去搜索”本身也要求对学科有一定深度的理解,不然你连问题都不知道怎么搜(当然,print()里打出引号还是很容易搜到的)。
最后,楼主求知的态度值得肯定,祝coding愉快。

12
0
回复

全部回帖 (11)


刘洋
71天前
查看回复(1)

节前摸鱼答一发。
这个问题不是所谓百度&Google&SOF能解决的,因为初学者缺少提问的经验(没错,提问也是门学问),几乎不可能找到正确的相关知识。
编程语言里面有个概念叫scope,常翻译为作用域。变量说白了就是个名字,作用域决定了哪些部分的代码可以获取到这个名字。
先看左边的代码,你在函数里执行x=x+1,这相当于告诉计算机:定义一个变量x,并且它的值是x+1。在“定义变量x”这一步,计算机创造了一个local variable x,这个x和外界的global variable x是不同的(本质上是内存地址不同),只是名字一样(这个现象叫shadowing)。所以在第二步自增的时候,在evaluate x+1时,计算机发现local x根本就没有声明&赋值过,就会报错。
右边的global关键词告诉计算机,这里我要用全局变量x,于是函数里就能获取到x的值,并进行自增操作。
不过在实践中,global是强烈不建议使用的。因为它会导致代码难以阅读和debug。
总结一下,这个case难以理解的原因在于:
1. Python is very simple, so even a single expression could involve a great set of complicated memory manipulations. Python简单易学的背后是极高的复杂度,因为语言实现者把复杂度屏蔽在了底层。于是,一个简单的=符号其实包含了内存分配、变量声明、赋值等一系列操作(Python不区分声明和赋值,新人更难以理解)。
2. 初学者缺乏底层知识。scope和shadowing的概念涉及到内存堆栈和函数生命周期的关系,在缺乏这些知识的情况下, 对这类现象不必过于深究,只需要懂一些表面即可。
其实我一直很反对无脑让新手百度的行为,因为其实“懂得如何去搜索”本身也要求对学科有一定深度的理解,不然你连问题都不知道怎么搜(当然,print()里打出引号还是很容易搜到的)。
最后,楼主求知的态度值得肯定,祝coding愉快。

12
0
回复 # 1

yousyahime
71天前
查看对话

刘洋:

节前摸鱼答一发。
这个问题不是所谓百度&Google&SOF能解决的,因为初学者缺少

顺便推荐下这个

代码问题可以贴在这里hh

0
0
回复 # 2

work007
71天前

自行搜索解决的方法,我来抛个砖

我Google了关键词“python global”,第一条里面就有一些正误案例(但是在原理上没2楼小哥哥/小姐姐讲的详细)

因此对某个keyword的用法完全不明白的话,可以用python+keyword为关键词搜索,看看前几条里面的例子也许就理解了

0
0
回复 # 3

yousyahime
70天前
查看回复(1)

能把在vsc中的报错发一下吗,看看能不能帮你

0
0
回复 # 4

qwerty
70天前

说句题外话,初学者学习 Python 的时候无法弄明白 global 的含义是很正常的。毕竟这个东西设计的就不是很合理。

我们可以看这样一个例子。

x = 1

def foo():
    x = 2

def bar():
    y = x + 2

def baz():
    x = x + 2

凭什么 baz() 就不能被处理为在 baz() 函数作用域内声明一个变量 x,然后 x 的值为全局变量 x 的值加上 2 呢?但是很遗憾,Python 的设计中不允许一个语句中相同的标识符具有不同的含义,所以 baz() 函数只能是错的。

因为 Python 在 syntax 上不区分声明和赋值,所以在一个函数作用域内,对于一个与全局变量相同的标识符 <id>,无法直接区分 <id> = <expr> 到底是对全局变量的赋值还是在函数作用域声明一个同名的变量。所以必须引入 global 这个关键字。

因此,在非纯函数式语言中,语法上不区分赋值和声明是一种严重的设计失误,因此绝大部分现代编程语言(Rust,Kotlin,Swift 等)即使有了自动类型推导,声明变量也是需要特别的关键字的,在语法上与赋值进行区分。

3
0
回复 # 5

Sisyphus
楼主
70天前
查看对话

yousyahime:

能把在vsc中的报错发一下吗,看看能不能帮你

白区代码报错情况如下,谢谢!

同时感谢所有层主

0
0
回复 # 6

yousyahime
70天前
查看对话

Sisyphus:

白区代码报错情况如下,谢谢!

同时感谢所有层主

你这报错有点诡异啊...你先检查下环境变量还有python插件吧...

0
0
回复 # 7

yousyahime
70天前
查看对话

Sisyphus:

白区代码报错情况如下,谢谢!

同时感谢所有层主

怎么说,看着有点神奇...

0
0
回复 # 8

yousyahime
70天前
查看对话

Sisyphus:

白区代码报错情况如下,谢谢!

同时感谢所有层主

我想了一下,嗯你是怎么运行python代码(py文件)的...
就你在文件内右键,有没有看到在终端中运行python文件的字样...

0
0
回复 # 9

Sisyphus
楼主
70天前
查看对话

yousyahime:

我想了一下,嗯你是怎么运行python代码(py文件)的...
就你在文件内右键,有没有看到在终端中

木有,只是在IDLE中点能Run...

0
0
回复 # 10

yousyahime
70天前
查看对话

Sisyphus:

木有,只是在IDLE中点能Run...

那就是你插件没安装,小事了…

google或百度搜一下插件怎么安装,出问题可以继续问我,或者qq564142445

0
0
回复 # 11


    请登录参与讨论 :)