python函数的参数、变量说明

参考

1.函数返回值return

  • 默认返回None
  • 函数执行到retrun后不继续往下执行
  • 可以有多个return(在不同条件下),同一时刻只能返回一个
  • 想要一次返回多个值可以直接放在retrun后,用逗号隔开(实际是一个元组)
    自动组包解包 https://ceshiren.com/t/topic/30328

2.函数参数

2.1位置参数/必备参数

  • 数量必须和定义时一致:抛出 TypeError 异常,提示missing x required positional argument
  • 位置必须与定义时一致:抛出 TypeError 异常或者结果与预期不符的情况。
def printMsg(n, msg):
    for i in range(n):
        print(f'第{i+1}次输出{msg}')

# 正确使用位置参数
printMsg(5, "Hogworts")
# 错误使用位置参数
printMsg("Hogworts", 5)# TypeError: 'str' object cannot be interpreted as an integer

2.2关键字参数

使用形式参数的名字来确定输入的参数值,不再需要与形式参数的位置完全一致,只要将参数名写正确即可。

def printMsg(n, msg):
    for i in range(n):
        print(f'第{i+1}次输出{msg}')

# 关键字参数
printMsg(n=5, msg="Hogworts")
printMsg(msg="Hogworts", n=5)

2.3默认参数

在定义函数时,形参可以定义变量一样进行赋值,这个值就是默认该参数的默认值。
注意:指定默认值的形式参数必须放在所有未指定默认值参数的后面

def my_power(m, n=2,a=1):
    return m ** n + a

# 使用指定的参数--通过位置进行传递
print(my_power(2, 3,2))# 10
# 使用指定的参数--通过参关键字传递
print(my_power(n=2, a=3,m=2))# 7
# 使用默认值参数
print(my_power(2))# 5
# 使用默认参数n,a实际传值
print(my_power(2,a=2))# 6
# n实际传值,使用默认参数a
print(my_power(2,n=3))# 9

2.4可变参数

Python中提供了可变参数的概念用来解决参数个数不确定的的情况

2.4.1 可变位置参数 *args

  • args作为形参,接收不确定个数的位置参数(*args将接收到的任意多实际参数放在元组中,元组名是args)
    • *args:元组内部的值,没有(),类似:1 2 3 。。。;
    • args:完整的元组数据,类似:(1,2,3…);
    • 也就是:传递给函数之后,*args和传递的内容一样,而args是给传递的值套了个“()”将其转成元组类型;

举例:

def fun(*args):
    print(args)    # 输出:(1, 2, 3)
    # 解包 
    print(*args)  # 输出:1 2 3
    print(type(args)) # 输出:<class 'tuple'>
    for i in args:
        print(i)

fun(1,2,3)

2.4.1 可变关键字参数 **kwargs

kwargs作为形参,接收不确定个数的关键字参数(*kwargs将接收到的任意多实际参数放在字典中,字典名kwargs)

举例:

def fun(**kwargs):
    print(kwargs)  # 输出:{'a': 1, 'b': 2, 'c': 3}
    # print(**kwargs) #会报错TypeError: 'a' is an invalid keyword argument for print()
    print(*kwargs)  #对字典的key解包,结果为: a b c
    for k,v in kwargs.items():
        print(k,v)

fun(a=1,b=2,c=3)

2.4.3 混合参数
当定义函数时,参数列表中出现了多种类型的参数,定义时需要注意参数的定义顺序,如果顺序使用不正确,在调用函数时,可能会报错。

正确顺序的定义为:位置参数,可变位置参数,默认值参数,可变关键字参数

def fun(name1,*args,age=1,**kwargs):
   pass

3 变量作用域

  • 变量的作用域决定了在哪一部分程序可以访问哪个特定的变量名称。Python 的作用域一共有4种,分别是:
    • L(Local):最内层,包含局部变量,比如一个函数/方法内部。
    • E(Enclosing):包含了非局部(non-local)也非全局(non-global)的变量,一般在闭包中出现。
    • G(Global):当前脚本的最外层,比如当前模块的全局变量。
    • B(Built-in): 包含了内置(内建)的变量/关键字等,最后被搜索。
    • 查找规则顺序: L –> E –> G –> B 。在局部找不到,便会去局部外的局部找(例如闭包),再找不到就会去全局找,再者去内置中找。

3.1局部变量
局部变量是指在函数内部定义并使用的变量。

  • 它只在函数内部有效,即函数内部的名字只在函数运行时才会创建,在函数运行之前或者运行完毕之后,所有的名字就被销毁都不存在了。
  • 如果在函数外部使用函数内部定义的变量,就会抛出 NameError 异常。

3.2全局变量

  • 定义在函数外的变量为全局变量,全局变量可以在当前程序文件的任何位置进行访问
  • 当全局变量和局部变量同名时,根据作用域的查找规则顺序,内部变量会屏蔽全局变量

全局变量主要有两种情况:
(1)如果一个变量在函数体外定义,那么不仅在函数外可以访问到,在函数内也可以访问到。在函数体以外定义的变量是全局变量。

msg = "学习测试开发来霍格沃兹测试学社" 
def var_demo():
    print("函数体内全局变量 msg 的值为", msg) 

var_demo()  
print("函数体外全局变量 msg 的值为", msg)
---------------------------------------------------------------
函数体内全局变量 msg 的值为 学习测试开发来霍格沃兹测试学社
函数体外全局变量 msg 的值为 学习测试开发来霍格沃兹测试学社

(2) 如果一个变量在函数体内定义,并且使用 global 关键字修饰后,该变量也就变为全局变量。在函数体外可以访问该变量,并且在函数体内还可以对其进行修改

msg = "学习测试开发来霍格沃兹测试学社" # 创建一个局部变量并赋值
print("函数体外全局变量 msg 的值为", msg) # 在函数体外输出局部变量的值
def var_demo():
    global msg
    msg = "霍格沃兹测试学社值得信赖" # 此时已经申明了 msg 为全局变量
    print("函数体内变量 msg 的值为", msg) # 输出局部变量 msg 的值

var_demo()   # 调用函数
print("函数体外全局变量 msg 的值为", msg) # 在函数体外输出局部变量的值
-------------------------------------------------------------------------------------------------------
函数体外全局变量 msg 的值为 学习测试开发来霍格沃兹测试学社
函数体内变量 msg 的值为 霍格沃兹测试学社值得信赖
函数体外全局变量 msg 的值为 霍格沃兹测试学社值得信赖

全局变量和局部变量优缺点:

  • 全局变量的优点:
      1. 全局变量在整个程序中都可访问,方便在不同的函数或模块之间共享数据
      1. 全局变量可以保存程序运行期间的状态,比如计数器或状态标志。
  • 全局变量的缺点:
      1. 全局变量的作用范围很大,容易被误修改,导致程序出现错误。
      1. 在多个函数中使用同名的全局变量时,很容易出现混淆和命名冲突的问题。
      1. 全局变量的使用不宜过多,因为它们会占用内存资源。如果程序中有太多的全局变量,会增加维护和调试的难度。
  • 局部变量的优点:
      1. 局部变量的作用范围限于所在的函数或代码块中,不会对其他函数或模块造成影响。这样可以防止变量的误修改或命名冲突。
      1. 局部变量仅在需要时才会被创建和销毁,节省了内存资源
  • 局部变量的缺点:
      1. 局部变量的作用范围有限,不能在其定义范围外直接访问。如果需要在多个函数之间共享数据,就不能使用局部变量,需要采用其他的方式来传递数据。
      1. 当函数中定义了较多的局部变量时,可能会使代码显得冗长和难以阅读,增加了编写和维护的复杂性。