天天看点

自学 Python 之函数的参数

微信公众号:一个优秀的废人

如有问题或建议,请后台留言,我会尽力解决你的问题。

自学 Python 之函数的参数

前言

我是狗哥,一名程序猿。做过 Android、撸过 Java、目前在自学 Python 。注册 「一个优秀的废人」这个公号已有些日子,真正有心将它运营起来是这两天萌生的想法。注册这个号的初衷是分享我的 Python 学习笔记。一个知识,你自己懂,不算是真的懂,你能把他人说懂,才是真正掌握。分享,是一个最好的复习过程。

什么是参数?

参数,也叫参变量,是一个变量。

简单来说,参数就是你调用函数时,根据需要传入的变量。比如说,某个函数的作用是计算长方形的面积,那当你调用此函数时就要传入长方形的长和宽这两个变量,才能计算出你想要的结果。

Python 中的参数分为以下四种类型:

  • 必需参数
  • 关键字参数
  • 默认参数
  • 不定长参数

下面我将逐个介绍:

必需参数

必需参数须以正确的顺序传入函数。调用时的数量必须和声明时的一样。

例如,下面调用printme()函数,你必须传入一个参数,不然会出现语法错误:

#可写函数说明
def printme( str ):
   "打印任何传入的字符串"
   print (str)
   return

#调用printme函数
printme()
           

如果你不传参,调用以上代码输出的结果会报错:

Traceback (most recent call last):
  File "test.py", line , in <module>
    printme()
TypeError: printme() missing  required positional argument: 'str'
           

关键字参数

关键字参数和函数调用关系紧密,函数调用使用关键字参数来确定传入的参数值。

使用关键字参数允许函数调用时参数的顺序与声明时不一致,因为 Python 解释器能够用参数名匹配参数值。

以下实例在函数 printme() 调用时使用参数名:

#可写函数说明
def printme( str ):
   "打印任何传入的字符串"
   print (str)
   return

#调用printme函数
printme( str = "自学 Python")
           

以上代码将根据参数名 str 传入参数值 “自学 Python” 输出结果:

自学 Python
           

另外,在传入关键字参数时,还不需要使用指定顺序:

#可写函数说明
def printinfo( name, age ):
   "打印任何传入的字符串"
   print ("名字: ", name)
   print ("年龄: ", age)
   return

#调用printinfo函数
printinfo( age=, name="Python" )
           

python 允许以上实例在调用函数时打乱参数顺序,输出结果:

名字:  Python
年龄:  666
           

默认参数

调用函数时,如果没有传递参数,则会使用默认参数。以下实例中如果没有传入 age 参数,则使用默认值:

#可写函数说明
def printinfo( name, age =  ):
   "打印任何传入的字符串"
   print ("名字: ", name)
   print ("年龄: ", age)
   return

#调用printinfo函数
printinfo( age=, name="Python" )
print ("------------------------")
printinfo( name="Python" )
           

输出结果:

名字:  Python
年龄:  24
------------------------
名字:  Python
年龄:  666
           

不定长参数

你可能需要一个函数能处理比当初声明时更多的参数。这些参数叫做不定长参数,和上述 2 种参数不同,声明时不会命名。基本语法如下:

def functionname([formal_args,] *var_args_tuple ):
   "函数_文档字符串"
   function_suite
   return [expression]
           

加了星号 * 的参数会以元组(tuple)的形式导入,存放所有未命名的变量参数。

# 可写函数说明
def printinfo( arg1, *vartuple ):
   "打印任何传入的参数"
   print ("输出: ")
   print (arg1)
   print (vartuple)

# 调用printinfo 函数
printinfo( , ,  )
           

输出结果:

输出: 
70
(60, 50)
           

如果在函数调用时没有指定参数,它就是一个空元组。我们也可以不向函数传递未命名的变量。如下实例:

# 可写函数说明
def printinfo( arg1, *vartuple ):
   "打印任何传入的参数"
   print ("输出: ")
   print (arg1)
   for var in vartuple:
      print (var)
   return

# 调用printinfo 函数
printinfo(  )
printinfo( , ,  )
           

输出结果:

输出:
10
输出:
70
60
50
           

不定长参数,还有一种格式就是参数带两个星号 **基本语法如下:

def functionname([formal_args,] **var_args_dict ):
   "函数_文档字符串"
   function_suite
   return [expression]
           

加了两个星号 ** 的参数会以字典的形式导入。

# 可写函数说明
def printinfo( arg1, **vardict ):
   "打印任何传入的参数"
   print ("输出: ")
   print (arg1)
   print (vardict)

# 调用printinfo 函数
printinfo(, a=,b=)
           

输出结果:

输出: 

{'a': , 'b': }
           

声明函数时,参数中星号 * 可以单独出现,例如:

def f(a,b,*,c):
    return a+b+c
           

如果单独出现星号 * 后的参数必须用关键字传入,否则将报错。

>>> def f(a,b,*,c):
...     return a+b+c
... 
>>> f(,,)   # 报错
Traceback (most recent call last):
  File "<stdin>", line , in <module>
TypeError: f() takes  positional arguments but  were given
>>> f(,,c=) # 正常

>>>
           

匿名函数

Python 使用 lambda 来创建匿名函数。

所谓匿名,意即不再使用 def 语句这样标准的形式定义一个函数。

  • lambda 只是一个表达式,函数体比 def 简单很多。
  • lambda的主体是一个表达式,而不是一个代码块。仅仅能在lambda表达式中封装有限的逻辑进去。
  • lambda 函数拥有自己的命名空间,且不能访问自己参数列表之外或全局命名空间里的参数。
  • 虽然lambda函数看起来只能写一行,却不等同于C或C++的内联函数,后者的目的是调用小函数时不占用栈内存从而增加运行效率。

语法格式

lambda 函数的语法只包含一个语句,如下:

以下代码演示了 lambda 表达式的用法:

# 可写函数说明
sum = lambda arg1, arg2: arg1 + arg2

# 调用sum函数
print ("相加后的值为 : ", sum( ,  ))
print ("相加后的值为 : ", sum( ,  ))
           

输出结果:

相加后的值为 :  30
相加后的值为 :  40
           

return 语句

return [表达式] 语句用于退出函数,选择性地向调用方返回一个表达式。不带参数值的 return 语句返回 None 。之前的例子都没有示范如何返回数值,以下实例演示了 return 语句的用法:

# 可写函数说明
def sum( arg1, arg2 ):
   # 返回2个参数的和."
   total = arg1 + arg2
   print ("函数内 : ", total)
   return total

# 调用sum函数
total = sum( ,  )
print ("函数外 : ", total)
           

输出结果:

函数内 :  30
函数外 :  30
           

变量作用域

Python 中,程序的变量并不是在哪个位置都可以访问的,访问权限决定于这个变量是在哪里赋值的。

变量的作用域决定了在哪一部分程序可以访问哪个特定的变量名称。Python 的作用域一共有 4 种,分别是:

  • L (Local) 局部作用域
  • E (Enclosing) 闭包函数外的函数中
  • G (Global) 全局作用域
  • B (Built-in) 内建作用域

以 L –> E –> G –>B 的规则查找,即:在局部找不到,便会去局部外的局部找(例如闭包),再找不到就会去全局找,再者去内建中找。

x = int()  # 内建作用域

g_count =   # 全局作用域
def outer():
    o_count =   # 闭包函数外的函数中
    def inner():
        i_count =   # 局部作用域
           

Python 中只有模块(module),类(class)以及函数(def、lambda)才会引入新的作用域,其它的代码块(如 if/elif/else/、try/except、for/while等)是不会引入新的作用域的,也就是说这些语句内定义的变量,外部也可以访问,如下代码:

>>> if True:
...  msg = 'Life is short and I use Python'
... 
>>> msg
'Life is short and I use Python'
>>> 
           

这里解析以下上述代码,,实例中 msg 变量定义在 if 语句块中,但外部还是可以访问的。

如果将 msg 定义在函数中,则它就是局部变量,外部访问会报错:

>>> def test():
...     msg_inner = 'I am from Runoob'
... 
>>> msg_inner
Traceback (most recent call last):
  File "<stdin>", line , in <module>
NameError: name 'msg_inner' is not defined
>>> 
           

从报错的信息上看,说明了 msg_inner 未定义,无法使用,因为它是局部变量,只有在函数内可以使用。

全局变量和局部变量

定义在函数内部的变量拥有一个局部作用域,定义在函数外的拥有全局作用域。

局部变量只能在其被声明的函数内部访问,而全局变量可以在整个程序范围内访问。调用函数时,所有在函数内声明的变量名称都将被加入到作用域中。如下实例:

total =  # 这是一个全局变量
# 可写函数说明
def sum( arg1, arg2 ):
    #返回2个参数的和."
    total = arg1 + arg2 # total在这里是局部变量.
    print ("函数内是局部变量 : ", total)
    return total

#调用sum函数
sum( ,  )
print ("函数外是全局变量 : ", total)
           

输出结果:

函数内是局部变量 :  30
函数外是全局变量 :  0
           

global 和 nonlocal关键字

当内部作用域想修改外部作用域的变量时,就要用到 global 和 nonlocal 关键字了。

以下实例修改全局变量 num:

num = 
def fun1():
    global num  # 需要使用 global 关键字声明
    print(num) 
    num = 
    print(num)
fun1()
           

输出结果:

1
123
           

如果要修改嵌套作用域(enclosing 作用域,外层非全局作用域)中的变量则需要 nonlocal 关键字了,如下实例:

def outer():
    num = 
    def inner():
        nonlocal num   # nonlocal关键字声明
        num = 
        print(num)
    inner()
    print(num)
outer()
           

输出结果:

100
100
           

另外有一种特殊情况,假设下面这段代码被运行:

a = 
def test():
    a = a + 
    print(a)
test()
           

以上程序执行,报错信息如下:

Traceback (most recent call last):
  File "test.py", line , in <module>
    test()
  File "test.py", line , in test
    a = a + 
UnboundLocalError: local variable 'a' referenced before assignment
           

错误信息为局部作用域引用错误,因为 test 函数中的 a 使用的是局部,未定义,无法修改。

修改 a 为全局变量,通过函数参数传递,可以正常执行输出结果为:

a = 
def test(a):
    a = a + 
    print(a)
test(a)
           

输出结果为:

11
           

后语

我不是大神,于 Python 领域来说,我是菜鸡,但谁刚开始接触一个领域的时候不是菜鸡呢。 写这个号的目的是为了记录我自学 Python 的笔记。

如果本文对你哪怕有一丁点帮助请右下角点赞,否则忽略就好。平时工作较忙,自学 Python 的时间较少,可能会学得慢点,希望大家多多指教。此处奉上思维导图:

自学 Python 之函数的参数

最后,如果对 Python 、Java 感兴趣请长按二维码关注一波,我会努力带给你们价值,赞赏就不必了,能力没到,受之有愧。

自学 Python 之函数的参数