【人生苦短,我学 Python】(10)pass语句、match语句、异常处理以及日志记录

发布时间:2024年01月19日
Python 所有文章传送门
【Python】所有文章传送门

简述 / 前言

上一篇文章讲了分支判断、循环、enumerate 函数和zip 函数,流程控制也差不多结束了,但是在我们学习 C 语言的时候,不知道大家还记不记得 C 语言有个 switch 语句,那么 Python 里面有没有 switch 语句呢?下面就给大家揭晓谜底,当然在此之前先补充一个 pass 语句~

另外本篇文章还会介绍异常处理以及日志记录

1. pass

pass 语句不执行任何动作。语法上需要一个语句,但程序毋需执行任何动作时,可以使用该语句。

比如你想好了一个函数(def)或者类(class)的名字,但是它具体要实现的功能还没想好,那么可以用 pass 代替你将要完成的功能,起码能保证程序运行来测试其他功能是否正常。pass 甚至在循环、分支也能用(可以在任何地方使用)。

示例:

for year in range(2020, 2024):
    pass

if 2 > 1:
    pass

def hello():
    pass

class People:
    pass

这个语句一般是在测试代码的时候可能用得上~

2. match

match 语句接受一个表达式并把它的值与一个或多个 case 块给出的一系列模式进行比较。这表面上像 C、Java 或 JavaScript(以及许多其他程序设计语言)中的 switch 语句,但其实它更像 Rust 或 Haskell 中的模式匹配。只有第一个匹配的模式会被执行,并且它还可以提取值的组成部分(序列的元素或对象的属性)赋给变量。

不过这个语句是 Python 3.10 以后才引入的,所以旧的 Python 版本是不支持这个语法的。

示例,编写 CSDN.py,代码如下:

import sys

x = float(sys.argv[1])
y = float(sys.argv[2])

point = (x, y)

match point:
    case (0, 0):
        print("Origin")
    case (0, y):
        print(f"Y={y}")
    case (x, 0):
        print(f"X={x}")
    case (x, y):
        print(f"X={x}, Y={y}")
    case _:
        raise ValueError("Not a point")

在终端(terminal)中输入(具体输入什么见下面代码):

D:\MyCode\Python_Code\PyCharm>python CSDN.py 0 0  
Origin

D:\MyCode\Python_Code\PyCharm>python CSDN.py 0 2.65
Y=2.65

D:\MyCode\Python_Code\PyCharm>python CSDN.py 3.1415 0
X=3.1415

D:\MyCode\Python_Code\PyCharm>python CSDN.py 3.1415 2023
X=3.1415, Y=2023.0

值得注意的是:Python 的 match 语句和 C 语言的 switch 语句不一样!!!

在 C 语言中,switch 语句要想在某一段case中停止的话,是需要加上 break 的,否则会一直执行下面的 case,而 Python 则是只匹配一个 case,其实这个 match 和 if-elif-else 实现的功能完全一样,只不过代码阅读起来会容易一些。

其次,Python 的 match 语句中的 case 不单单是只能匹配一个值,还能配上 if 语句:

flag = False
match (100, 200):
    case (100, 300):  # Mismatch: 200 != 300
        print('Case 1')
    case (100, 200) if flag:  # Successful match, but guard fails
        print('Case 2')
    case (100, y):  # Matches and binds y to 200
        print(f'Case 3, y: {y}')
    case _:  # Pattern not attempted
        print('Case 4, I match anything!')

输出:

Case 3, y: 200

是不是出乎意料呢?(100, 200) 不是和 case (100, 200) if flag 完全匹配吗,其实正是因为后面附属的 if flag 为假(False)导致整个 case 为假,在这里是 and 操作。


另外,在匹配值时可以用 |(或),这样只要满足其中一个条件就会输出结果,而 ,(逗号)表示 ~ 表示

示例【判断输入的数据是什么类型】:

def category(val):
    match val:
        case float() | int():
            print(f'你输入的 {val} 是一个数字')
        case list() | tuple():
            print(f'你输入的 {val} 是一个序列')
        case str():
            print(f'你输入的 {val} 是一个字符串')
        case dict():
            print(f'你输入的 {val} 是一个字典')
        case None:
            print(f'你输入的 {val} 为空')
        case _:
            print(f'你输入的 {val} 是其它类型')


category(3.14)
category(2024)
category([1, 2, 3])
category((1, 2, 3))
category('小邓在森林')
category({'age': 18, 'name': '小邓在森林'})
category(None)

输出:

你输入的 3.14 是一个数字
你输入的 2024 是一个数字
你输入的 [1, 2, 3] 是一个序列
你输入的 (1, 2, 3) 是一个序列
你输入的 小邓在森林 是一个字符串
你输入的 {'age': 18, 'name': '小邓在森林'} 是一个字典
你输入的 None 为空

3. 异常处理

异常处理就是指 Python 面对程序出现错误(异常)时如何去解决这些异常,保证程序不会正常运行而不会终止。

3.1 常见异常

  • NameError:尝试访问一个未申明的变量。
    >>> apple
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    NameError: name 'apple' is not defined. Did you mean: 'tuple'?
    
  • SyntaxError:语法错误。
    >>> apple =
      File "<stdin>", line 1
        apple =
                ^
    SyntaxError: invalid syntax
    
  • AttributeError:访问未知对象属性。
    >>> apple = 'apple'
    >>> apple.eat()
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    AttributeError: 'str' object has no attribute 'eat'
    
  • TypeError:类型错误。
    >>> 'apple' + 2023
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    TypeError: can only concatenate str (not "int") to str
    
  • ValueError:数值错误。
    >>> int('apple')
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    ValueError: invalid literal for int() with base 10: 'apple'
    
  • ZeroDivisionError:零除错误。
    >>> 2023 / 0
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    ZeroDivisionError: division by zero
    
  • IndexError:索引超出范围。
    >>> l = [1, 2]
    >>> l[2]
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    IndexError: list index out of range
    
  • KeyError:关键字不存在。
    >>> d = {'age': 18, 'name': '小邓在森林'}
    >>> d['hobby']
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    KeyError: 'hobby'
    

3.2 抛出异常

关键语句:raise ...

示例:

>>> age = 500
>>> if age>200: raise ValueError('年龄不能超过200岁')
...
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: 年龄不能超过200

4. 日志记录

我们可以使用模块 logging 来记录日志。

我们一般会把日志输出为一个文件,那么关键语句就是:logging.basicConfig(filename=filename, level=level, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'),各参数含义如下:

参数含义
filename要输出的日志文件名
level要输出的日志等级,可以选:logging.DEBUG, logging.INFO, logging.WARNING, logging.ERROR, logging.CRITICAL,选前面的 level 可以输出后面的信息,选后面的 level 不能输出前面的信息【比如选了 logging.WARNING,那么日志只会输出 (logging.WARNING, logging.ERROR, logging.CRITICAL) 这三个信息,而不会输出 (logging.DEBUG, logging.INFO) 这两个信息】
format要输出的信息格式

示例:

import logging

logging.basicConfig(filename="logging.txt", level=logging.WARNING, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')
# 输出日志信息
logging.debug("调试信息")       # 信息不输出
logging.info("一般信息")        # 信息不输出
logging.warning("警告信息")
logging.error("错误信息")
logging.critical("严重错误")

输出的文件内容:

2024-01-19 15:11:55,252 - root - WARNING - 警告信息
2024-01-19 15:11:55,252 - root - ERROR - 错误信息
2024-01-19 15:11:55,252 - root - CRITICAL - 严重错误
文章来源:https://blog.csdn.net/senlin_6688/article/details/135142460
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。