大蟒蛇python教程共享详解Python的函数与异常

目录
  • 1. 函数
    • 1.1 自定义函数
    • 1.2 函数与参数
    • 1.3 函数与返回值
  • 2. 异常处理
    • 2.1 raise 语句
    • 2.2 异常捕获
    • 2.3 finally 子句
  • 总结

    1. 函数

    抽象是程序能够被人理解的关键所在。程序应非常抽象,如获取用户输入构造列表,查找列表中最大的值,并进行打印:

      list_a = get_input()  max_value = max(list_a)  print(max_value)  

    看到这些代码,可以很容易这个程序是做什么的,至于这些操作的具体细节,将在独立的函数中给出。

    虽然我们并没有具体讲解过函数定义,但是我们已经使用过python 的内置函数 print,input 等。函数可用于减少代码重复,并使程序更易于理解和维护。可以将函数理解为一个“子程序”:函数本质上是一个命名语句序列,可以通过引用函数名称,在程序中的任何位置执行这些指令。创建函数的代码称为“函数定义”,当函数在程序中使用时,称为函数被“调用”。

    1.1 自定义函数

    通过定义函数可以隐藏计算细节,函数定义需要一个函数名、一系列参数(也可以不使用参数)以及一个函数体,函数也可以显式地返回一个值,函数定义的一般形式如下所示:

      def name_of_function(paramters):      body_of_function  

    例如编写一个求圆面积的函数:

      def area_of_circle(radius):      area = 3.14 * radius ** 2      return area  

    在这个函数定义中,def 是告诉 python 要定义一个函数,函数名(这里为 area_of_circle )用于函数后续的调用,函数名后的括号里是函数的形式参数列表。在这个函数中,radius 是唯一的形式参数,函数体可以是任何一段 python 代码,return 语句用于调用函数时返回一个值,只能用于函数体中,执行 return 语句会结束对函数的调用。如果要调用 area_of_circle 函数,需要为其提供一个实际参数值,函数调用是一个表达式,表达式的值就是调用函数返回的值:

      >>> area_of_circle(10)  314.0  >>> area = area_of_circle(10)  >>> print(area)  314.0  

    函数被调用时,将执行以下过程:

    1.调用程序在函数调用点暂停执行

    2.函数形参获得实参提供的值

    3.执行函数体中的代码,直至遇到 return 语句,return 后面的表达式的值作为函数调用的值;或者直到函数体中没有语句可以继续执行,这时函数返回的值为 none;

    4.如果 return 后面没有表达式,返回的值也为 none返回到函数被调用的点执行之后的代码

    详解Python的函数与异常

    我们已经知道,函数也可以不包含参数或返回值,例如以下简单的函数示例:

      def hello_world():      for i in range(3):          print('hello world!')  

    调用此函数,将打印三行 ‘hello world!’,且函数的返回值为 none:

      >>> value = hello_world()  hello world!  hello world!  hello world!  >>> print(value)  none  

    1.2 函数与参数

    编写函数时,常常需要多个参数,那么不同参数是如何赋值的呢?在 python 中,有两种方法可以将形参绑定到实参。最常用的方法是使用位置参数,即第一个形参绑定到第一个实参,第二个形参绑定到第二个实参,以此类推;第二种方法是关键字参数,即形参根据名称绑定到实参:

      def inforname(name, sex, address):      print("my name is {}, my gender is {}, and my home address is {}.".format(name, sex, address))  

    以下几种函数调用方式是等价的,其中第一种方式为位置参数,其他方法为关键字参数

      inforname('panxiaohui', 'male', 'henan')  inforname('panxiaohui', address = 'henan', sex = 'male')  inforname('panxiaohui', 'male', address = 'henan')  inforname(address = 'henan', sex = 'male', name = 'panxiaohui')  

    关键字参数可以放在位置参数后,但位置参数不能放在关键字参数后:

      >>> inforname('panxiaohui', sex = 'male', 'henan')    file "<stdin>", line 1      inforname('panxiaohui', sex = 'male', 'henan')                                                   ^  syntaxerror: positional argument follows keyword argument  

    前面我们在介绍 print 函数时,提到过可以使用可选参数 end 来改变 print 函数默认换行的行为,可选参数是带有默认值的参数,通常和关键字参数结合使用,在函数调用时可以不为其赋值(此时将使用默认值),而不带有默认值的参数,在函数调用时则必须为其指定参数值。

    首先编写以下函数:

      def special_number(start, end, step=1):      list_value = []      for i in range(start, end, step):          list_value.append(i)      return list_value  

    执行函数调用:

      >>> special_number(2,10)  [2, 3, 4, 5, 6, 7, 8, 9]  >>> special_number(2,10, step=2)  [2, 4, 6, 8]  >>> special_number(2)  traceback (most recent call last):    file "<stdin>", line 1, in <module>  typeerror: special_number() missing 1 required positional argument: 'end'  

    1.3 函数与返回值

    返回值是从函数发送信息到调用函数的程序部分的主要方式,函数还可以通过更改函数参数来与调用程序通信,这需要理解函数调用中使用的实参和形参之间的关系。

    在函数中,尽管实参和形参的名称是一样的,但它们并不是同一个变量。每个函数都定义了一个命名空间,也称为作用域,每次函数调用都将创建一个新的作用域:

      def exponentiation(number, power):      power = power * 2      result = number ** power      number = result  def test_exponentiation():      n = 2      power = 5      exponentiation(n, power)      print(n, power)  

    调用函数,可以直观的看出作用域的含义:

      >>> test_exponentiation()  2 5  

    在函数内使用的变量称为局部变量(与之相对的是全局变量)。test_exponentiation() 函数的前两行创建了名为 original  power 的两个局部变量,它们的值分别为 2 和 5。 然后调用了 exponentiation() 函数。形参 number 和 power 被赋值为来自实参 original 和 power 的值。需要牢记一点,即使实参和形参的名称都为 power,它们也是两个独立的变量,参数的赋值使 test_exponentiation() 函数中的变量 original 和 power 引用了实参的“值”:

    详解Python的函数与异常

    执行 exponentiation() 首先为其局部变量 power 赋一个新值,并创建一个新变量 result。然后,exponentiation() 为 number 赋值,让它具有与 result 相同的值。虽然,现在 number  result 指向相同的值、并且修改了 exponentiation()函数中 power 变量,但这对 test_exponentiation() 函数中的变量 original 和 power 没有影响:

    详解Python的函数与异常

    exponentiation() 执行完成后,控制返回到 test_exponentiation()exponentiation() 中的局部变量被回收,test_exponentiation() 函数中的 original 和 power 仍分别指初始值。

    综上,python 中函数的形参只接收实参的“值”,函数不能访问保存实参的变量。因此,为形参分配新值对实参变量没有影响,这是由于 python “按值”传递所有参数。一些编程语言(如 c++ )允许变量本身作为参数传递给函数,这种机制称为“按引用”传递参数。当变量按引用传递时,向形参分配新值实际上会更改调用程序中的参数变量的值。

    由于 python 不允许按引用传递参数,因此需要使用 return 语句返回修改后的值:

      def exponentiation(number, power):      power = power * 2      result = number ** power      number = result      return number, power  def test_exponentiation():      original = 2      power = 5      original, power = exponentiation(original, power)      print(original, power)  

    执行函数,查看输出:

    >>> test_exponentiation()
    1024 10

    2. 异常处理

    程序编写过程中,有两种常见的错误:第一种时语法错误,例如编写程序时缩进出现问题、第二种问题是算法的逻辑错误,例如访问不存在的变量、列表越界访问等。后者通常称为异常,为了处理这种情况,python 提供了异常处理机制:

      >>> x = []  >>> x[0]  traceback (most recent call last):    file "<stdin>", line 1, in <module>  indexerror: list index out of range  

    在 python 中,异常状态使用异常对象来表示,在遇到错误时引发异常。如果未处理异常对象,程序将会终止并显示错误消息 (traceback)。每种异常也都是不同异常类的实例(上一示例中异常是类 indexerror 的实例),可以使用不同方式引发并捕获这些实例,而不至于导致整个程序运行失败。

    2.1 raise 语句

    可以使用 raise 语句来引发异常,并将类或实例作为参数。将类作为参数时,将自动创建一个实例,同时也可以添加错误消息提示:

      >>> raise oserror  traceback (most recent call last):    file "<stdin>", line 1, in <module>  oserror  >>> raise oserror("can't open this file")  traceback (most recent call last):    file "<stdin>", line 1, in <module>  oserror: can't open this file  

    2.2 异常捕获

    当程序发生异常时,也称程序“抛出”异常。对异常进行处理,通常称为异常捕获。为此,可使用 try/except 语句。例如,进行除法运算时,如果用户输入了一个非零的除数,那么运算结果就会被打印出来。但是,如果用户输入了一个零作为除数,那么就会引发 zerodivisionerror 异常:

      >>> number_a = float(input('please enter a number: '))  please enter a number: 10.2  >>> number_b = float(input('please enter another number: '))  please enter another number: 0  >>> print(number_a / number_b)  traceback (most recent call last):    file "<stdin>", line 1, in <module>  zerodivisionerror: float division by zero  

    使用 except 语句块则可以“捕捉”这个异常,并且打印提示消息,然后通过对除数加一个很小的值确保其不为零,这意味着程序并不会终止,而是继续执行后续语句:

      >>> try:  ...     print(number_a / number_b)  ... except:  ...     print('divisor cannot be zero!')  ...     print('add a small number to the divisor.')  ...     print(number_a / (number_b + 1e-8))  divisor cannot be zero  add a small number to the divisor  1019999999.9999999  

    如果需要捕获多个异常,可以使用多个 except 子句,或者在一个元组中指定这些异常:

      # 使用多个 except 子句  try:      number_a = input('please enter a number:')      number_b = input('please enter another number:')      print(float(number_a) / float(number_b))  except typeerror:      print("that wasn't a number!")  except zerodivisionerror:      print('divisor cannot be zero!')  # 使用元组指定异常  try:      number_a = input('please enter a number:')      number_b = input('please enter another number:')      print(float(number_a) / float(number_b))  except (zerodivisionerror, typeerror):      print("you entered the wrong number!")  

    try/except 语句还有一个可选的 else 子句,如果使用这个子句,那么必须放在所有的 except 子句之后,else 子句在 try 子句没有发生任何异常时执行,例如在 try 语句中执行除法运算,如果正确运算没有发生异常,则执行 else 部分,打印结果:

      try:      number_a = input('please enter a number:')      number_b = input('please enter another number:')      result = float(number_a) / float(number_b)  except (zerodivisionerror, typeerror):      print("you entered the wrong number!")  else:      print(result)  

    不把所有语句都放在 try 子句,而使用 else 子句,可以避免一些意料之外,而 except 又无法捕获的异常。

    2.3 finally 子句

    finally 子句可以与 try 语句配套使用,可以在发生异常时执行清理工作,不管 try 子句中是否发生异常,都将执行 finally 子句:

      result = none  try:      number_a = input('please enter a number:')      number_b = input('please enter another number:')      result = float(number_a) / float(number_b)  except (zerodivisionerror, typeerror):      print("you entered the wrong number!")  else:      print(result)  finally:      del result  

    总结

    本篇文章就到这里了,希望能够给你带来帮助,也希望您能够多多关注<计算机技术网(www.ctvol.com)!!>的更多内容!

    需要了解更多python教程分享详解Python的函数与异常,都可以关注python教程分享栏目—计算机技术网(www.ctvol.com)!

    本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。

    ctvol管理联系方式QQ:251552304

    本文章地址:https://www.ctvol.com/pythontutorial/964429.html

    (0)
    上一篇 2021年12月2日
    下一篇 2021年12月2日

    精彩推荐