关于全局变量、局部变量、形参、实参的一点感悟

2019-03-04  本文已影响0人  子恒__

作者:子恒

这个感悟是在做一道题中产生的,题目其实很简单,如下:

下列两个组代码分别输出的结果是什么?

def num_value(num1):
    num1 = 2

num1 = 1
num_value(num1)
print(num1)
def num_value(num1):
    global num1
    num1 = 2

num1 = 1
num_value(num1)
print(num1)

我最初的答案是:2,2
然而正确答案是:1,2


复盘一下我做这道题时候的错误思考:


看了正确答案之后我格外懵逼,我不明白第一组代码为什么明明在函数内num1的赋值变为了2但是程序输出的结果却是1。于是我把题目和我的疑惑发到python学习群里,有人建议我在函数内num1 = 2之前和之后都加上print(num1)之后再运行一下程序看看。代码如下:

def num_value(num1):
    print(num1)
    num1 = 2
    print(num1)

num1 = 1
num_value(num1)
print(num1)

输出结果如下:

1
2
1

前两个结果在函数内的输出结果,如我所料,可是奇怪的是赋值完毕跳出函数的时候num1又神奇的变回了1

后来群里的人提到了传值传址并且发给我了一个解释这个原因的文章链接:

详解python函数传参是传值还是传引用文章中全都是这样的论述:
Python参数传递采用的是“传对象引用”的方式。这种方式相当于传值和传引用的一种综合。如果函数收到的是一个可变对象(比如字典或者列表)的引用,就能修改对象的原始值,相当于通过“传引用”来传递对象。如果函数收到的是一个不可变对象(比如数字、字符或者元组)的引用,就不能直接修改原始对象--相当于通过“传值'来传递对象。

文章过于专业,反而整的更深奥了。我思考之后是这么理解的:

于是我对题目内的第一组代码进行改写,以进行验证。


实验1:把函数num_value(num1)赋值给函数外的num1

def num_value(num1):
    print(num1)
    num1 = 2
    print(num1)

num1 = 1
num1 = num_value(num1)
print(num1)

实验1输出结果如下:

1
2
None

实验2:在函数内加入return num1来返回函数内num1的值,并把函数num_value(num1)赋值给函数外的num1

def num_value(num1):
    print(num1)
    num1 = 2
    print(num1)
    return num1

num1 = 1
num1 = num_value(num1)
print(num1)

实验2输出结果如下:

1
2
2

两个实验证明了我的理解是对的,在第一个实验中,因为函数num_value(num1)没有再函数内返回任何值出来,所以是一通毫无意义的操。此时把num_value(num1)赋值给函数外的num1,自然输出了None。当我在函数内填入了返回值return num1之后,再次运行程序的结果输出为2

至此,我对局部变量、全局变量、实参、形参有了一个更清晰而深刻的认识。

我想,函数相关知识是python初阶的重点难点,可能对于大多数人来说很简单的这样一道题如果我只是似懂非懂的放过去了(之前也做过一道类似的题,我也做错了,但是放过去了),那么真正到使用的时候会遇到更多的困惑,会写出更“魔幻”的代码。

学习编程是绝对的需要理论与实践紧密结合的。

听课看书之后以为自己懂了,十有八九上手时候问题百出;实践之后代码跑成了就认为自己会了,碰到原理问题,十有八九还是混混沌沌。前者纸上谈兵,根本无法胜任实际的编程工作。后者把写代码变成了看运气看命的玄学,并不能在行业内有长足的发展。

到处都是xx天编程速成的宣传文案,看着让人心动,其实何来速成,又哪里有捷径。

速成来的东西,终究还是不能长久。要想有更好的发展,也只有学习更多看似枯燥的基础知识,多练习、多自我延伸探究、多把过往知识横向连接。

一定要知其然且知其所以然

上一篇下一篇

猜你喜欢

热点阅读