写给Python社群的第5课:Python 函数,真的难吗?

⛳️ 函数简介

这篇博客给大家带来的是 Python 函数,每次讲解到函数的时候,都会有很多同学掉队,其核心原因是思维的转变,在前文的几篇博客中,都是以线性思维进行说明,翻译成编程逻辑就是顺序思维,加入函数之后,顺序思维会因为函数而发生跳转,即进入函数,跳出函数的逻辑反复出现,所以初学者在学习阶段,很容易迷惑。

这时在回忆一下,你在使用函数的时候无需知道函数内部的代码是如何实现,而只需要知道函数名和参数,以及函数返回的结果即可使用对应函数。

函数最基础的应用场景就是把相同的代码抽离出来,独立实现一个功能,然后反复调用!

⛳️ 函数实战

函数是封装好的功能代码,其可以反复被调用,语法格式如下。

def 函数名([参数[,更多参数]]):
    函数体
    [return 返回值]

其中中括号内容都属于可选内容,如果去除这部分之后,你会发现一个精简的函数声明语法。

def 函数名():
    函数体

其中 def 作为函数声明的关键字出现,函数名需要遵守命名规则,即见名知义,小括号中的参数为可选内容,其后跟英文冒号,函数体是实现函数功能的核心代码, return 语句是函数的返回值。

函数定义的正式学习都是从无参函数开始的,我们定义一个返回【你好】的函数。

def my_func():
    return "你好"

my_func()

定义函数之后,如果希望使用函数,直接采用 函数名+小括号的格式调用即可,例如上述代码的 my_func() 调用 。

无参函数是最简单的函数定义形式,在此基础上可以携带一个参数,例如下述代码。

def my_func(name):
    print(name,'你好')

my_func('橡皮擦')
def my_func(name):
    print(name,'你好')

my_func(name = '橡皮擦')

调用函数传递参数的之后,在小括号中指定了参数名 name,同时为其赋值 橡皮擦,有了该概念之后,又可以引出来函数定义时,定义多个参数的问题。

def my_func(name,age):
    print(name,'你好!''你的年龄是',18)

my_func(name = '橡皮擦',age=18)

如果在调用函数时,不主动指定参数名,那默认按照参数位置进行匹配,例如下述代码。

def my_func(name,age):
    print(name,'你好!''你的年龄是',18)

my_func( '橡皮擦',18)

还需要注意,在传递参数时,指定参数名,必须放在函数传递参数实参时的尾部,下述代码是 错误的。

def my_func(name,age):
    print(name,'你好!''你的年龄是',18)

my_func( name = '橡皮擦',18)

错误提示如下:

  File "", line 4
    my_func( name = '橡皮擦',18)

^
SyntaxError: positional argument follows keyword argument

错误信息为语法错误,内容是位置参数被放在了关键字参数后。

前面又出现了几个新鲜概念,第一个是 实参,与之对应的概念是 形参,函数在声明的时候,使用的占位参数是形参,函数调用的时候,传递的参数实际值是实参,你可以基于这两个概念,再看一下前文所涉及内容。

上面还提及了位置参数和关键字参数,在后文函数参数一节,详细给大家说明。

函数的返回值属于函数可选项,即函数是可以不带返回值的,如果没有显示使用 return 设置返回值,函数在使用完毕,会默认返回 None, return 语句除了用作函数返回值的关键字,其还携带一个阻止函数继续运行的功能,即当运行时环境发现 return 关键字之后,后续代码全部忽略执行。

def my_func(name,age):
    if age >=18:
        return '成年'

    else:
        return '年轻人'
my_func('橡皮擦',18)

函数的参数属于函数这一节知识点中最复杂的一块了,原因是其组合形式极多,接下来为大家逐一展示。

位置参数
什么是位置参数,在传输参数的时候,形参和实参位置一一对应,顺序不能乱,例如下述代码。

def my_func(name,age):
    if age >=18:
        return '成年'

    else:
        return '年轻人'
my_func('橡皮擦',18)

如果在向函数传递值的时候,把参数位置给混淆了,即出现如下场景。

def my_func(name,age):
    if age >=18:
        return '成年'

    else:
        return '年轻人'
my_func(18,'橡皮擦')

上述代码运行会直接报错,原因就是实参位置无法对应准确。
关键字参数
关键字参数其实说的是实参位置代码的写法,即使用 参数名=值 的格式进行传递,用该方法可以防止参数传递出错,例如修改上述代码为如下内容。

def my_func(name,age):
    if age >=18:
        return '成年'

    else:
        return '年轻人'
my_func(age = 18,name = '橡皮擦')

代码立刻可以执行,即函数在调用时,指定参数名和对应值,无需考虑参数位置。
参数默认值
在函数声明的时候,可以给参数一个缺省值,这样即使调用者没有给该函数赋值,代码也可正常运行。

def my_func(name,age=19):
    if age >=18:
        return '成年'

    else:
        return '年轻人'
my_func(name = '橡皮擦')

参数默认值,可以看作带可选参数的函数定义形式。

def my_func(name,age,*vars):
    print(name)
    print(age)
    print(vars)
my_func('橡皮擦',19,1,2,3,4)

运行代码,会发现输出 vars 时,会打印一个元组,将 (1,2,3,4) 都进行了打包输出。

特别注意:在定义函数时,只能有一个 *vars,而且只能放在最右侧,所以下述声明都是错误的。
def my_func(name,age,vars1,vars2):
def my_func(name,*vars,age):

接下来在说明一个 **kws 参数,在函数定义的时候,可以在参数表末尾追加该形参,其表示接收任意数量的键值对,示例代码如下:

def my_func(name,age,**kws):
    print(name)
    print(age)
    print(kws)
my_func('橡皮擦',19,s='女',g='1',bl='234')

**kws 参数也必须放在参数表最右侧,如果有 *vars,注意它需要在 *vars 右侧,即下述格式。

def my_func(name,age,*vars,**kws):
    print(name)
    print(age)
    print(vars)
    print(kws)
my_func('橡皮擦',19,9,s='女',g='1',bl='234')

上述代码虽然简单,但是包含了所有参数格式,我们依次看一下。

  • 橡皮擦19 分别匹配了参数表中的 nameage 两个形参;
  • 19 无匹配值,并且是以位置参数进行的传递,所以其被 *vars 捕获;
  • s='女‘, g='1'bl='234' 由于其为关键字格式传递参数值,所以 *vars 无法捕获,被 **kws 捕获到。

肯定有同学问 *vars**kws 实战中有何用途呢?直接声明参数不好吗?

注意这里的 vars 和 kws 只是普通的变量名,可以自行替换。

答案如下,当我们向函数传递元组,列表,字典的时候,就会发现其价值,请查看下述函数声明。

my_tuple = ('橡皮擦',18,'年轻','女','研究生','985/211')
def show_info(*vars):
    print(vars)

show_info(my_tuple)

可以看到,在上述代码中,我们的形参表只有一个 *vars,就可以完整的捕获整个元组,大幅度的减少了编码难度。

同样的道理,你可以尝试将字典搭配 **kws 使用,看一下是否可能精简你的 Python 代码。

刚刚过去函数参数,又到了函数作用域这一难点了,作用域知识会贯穿整个 Python 生涯,由于其知识点比较隐蔽,而且被遗忘的概率极高,所以作用域一直是初学 Python 时的大挑战。

第一个要理解的知识点是作用域知识指的的 变量的作用域,所有后文讨论的都是变量内容。

先来看一下全局作用域和局部作用域这两个概念,在简化一下概念,咱们首先要学习的是全局变量和局部变量。

全部变量自赋值开始,后续任何代码块都可以访问该变量,而局部变量不可以,只能在定义它的函数内部访问。

下面我们进行一下代码演示。

name = '橡皮擦'
def show():
    print(name)

show()
print(name)

此时运行代码会输出两个【橡皮擦】,该内容表示 name 作为全局变量,可以在函数内部被访问到,这里会产生一个知识点,如果你希望在函数内部修改全局变量,是否可以实现。

name = '橡皮擦'
def show():
    name = '大橡皮'
    print(name)

show()
print(name)

运行代码,发现最后一行代码输出的依旧是【橡皮擦】,函数内部的重新赋值 name='大橡皮' 并未生效,函数外访问依旧是原值,如果希望在函数内部修改全局变量,需要使用关键字 global,修改上述代码。

name = '橡皮擦'
def show():
    global name
    name = '大橡皮'
    print(name)

show()
print(name)

在函数内部使用全局变量前,增加了一个 global name,该语句表示函数内的 name 参数是全局变量,修改之后会影响到全局。

在程序编码实战中,不建议过多的使用 global 关键字,因其会导致变量作用域发生混乱。

📢📢📢📢📢📢
💗 你正在阅读 【梦想橡皮擦】 的博客
👍 阅读完毕,可以点点小手赞一下
🌻 发现错误,直接评论区中指正吧
📆 橡皮擦的第 743 篇原创博客

从订购之日起,案例 5 年内保证更新

Original: https://blog.csdn.net/hihell/article/details/127599743
Author: 梦想橡皮擦
Title: 写给Python社群的第5课:Python 函数,真的难吗?

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/673217/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球