day-009–补充知识点2

补充知识点2

补充知识点1增加以下几个:

  • 错误和异常
  • 标准库概览

1. 错误和异常

错误分两种,一种就是你写错了,语法错误,另一种就是异常了

1.1错误

语法错误就是这个样子,ide其实会提示你的

if 1 < 2
    print('errror')

输出

  File "D:/python/day009.py", line 1
    if 1 < 2
           ^
SyntaxError: invalid syntax

看看ide的提示:


image.png

告诉你需要一个冒号
处理办法就是加上冒号就信不过

1.2 异常

在运行它的时候,也有可能发生错误。运行期检测到的错误被称为异常。
大多数的异常都不会被程序处理,都以错误信息的形式展现在出来
比如:

print(1/0)

结果:

Traceback (most recent call last):
  File "D:/python/day009.py", line 4, in <module>
    print(1/0)
ZeroDivisionError: division by zero

除数不能为0,ZeroDivisionError是错误类型
这样程序就会中断运行,所以不能出异常,出了也要去处理

下面通过以下几个方面来讲异常:

  • 异常处理
  • 抛出异常
  • 用户自定义异常
  • 定义清理行为
  • 预定义的清理行为
  • assert(断言)
1.2.1 异常处理

这里就是抓住异常并且处理,用的是try except
实例1:

while True:
    try:
        a = int(input('test except:'))
        print(a)
        print(100/a)
    except ZeroDivisionError as err0:
        print('Zero:', err0)
    except KeyboardInterrupt as err1:
        print('\nKey:', err1)
    except ValueError as err2:
        print('Value:',err2)
    else:
        print('happy!')
test except:123
123
0.8130081300813008
happy!
test except:aaa
Value: invalid literal for int() with base 10: 'aaa'
test except:0
0
Zero: division by zero
test except:
Key:
test except:

while 千万不要随便接受 KeyboardInterrupt,不然就一直停不下来,很烦

try语句按照如下方式工作;

  • 首先,执行try子句(在关键字try和关键字except之间的语句)
  • 如果没有异常发生,忽略except子句,try子句执行后结束。
  • 如果在执行try子句的过程中发生了异常,那么try子句余下的部分将被忽略。如果异常的类型和 except 之后的名称相符,那么对应的except子句将被执行。最后执行 try 语句之后的代码。
  • 如果一个异常没有与任何的except匹配,那么这个异常将会传递给上层的try中。
  • 一个 try 语句可能包含多个except子句,分别来处理不同的特定的异常。最多只有一个分支会被执行。
  • 处理程序将只针对对应的try子句中的异常进行处理,而不是其他的 try 的处理程序中的异常。
  • 一个except子句可以同时处理多个异常,这些异常将被放在一个括号里成为一个元组,例如:
    except (ZeroDivisionError,KeyboardInterrupt,ValueError):
        pass

pass是个空语句,为了好看

可以except 后面不加异常名称,通配所有异常,然后可以处理,想再扔出来就用raise

    except:
        print('catch error')
        raise

最后面可以跟一个else:这个看实例1

1.2.2 抛出异常

Python 使用 raise 语句抛出一个指定的异常
例如:

while True:
    try:
        a = int(input('test except:'))
        print(a)
        print(100/a)
    except:
        print('catch error')
        raise

结果:

test except:0
0
catch error
Traceback (most recent call last):
  File "D:/python/day009.py", line 10, in <module>
    print(100/a)
ZeroDivisionError: division by zero

就这样子

1.2.3 用户自定义异常

就是继承下 Exception类,并且重写__str__函数
这个样子:

class MyError(Exception):
    def __init__(self, value):
        self.value = value
    def __str__(self):
        return repr(self.value)
try:
    raise MyError(2*2)
except MyError as e:
    print('My exception occurred, value:', e.value)
    raise MyError('oops!')

结果

My exception occurred, value: 4
Traceback (most recent call last):
  File "D:/python/day009.py", line 32, in <module>
    raise MyError(2*2)
__main__.MyError: 4
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
  File "D:/python/day009.py", line 35, in <module>
    raise MyError('oops!')
__main__.MyError: 'oops!'

一样被捕获,在抛出第一个异常的时候,我触发了第二个

想要自己搞个异常模块的话,可以这样:

class Error(Exception):
    """Base class for exceptions in this module."""
    pass
 
class InputError(Error):
    """Exception raised for errors in the input.
 
    Attributes:
        expression -- input expression in which the error occurred
        message -- explanation of the error
    """
 
    def __init__(self, expression, message):
        self.expression = expression
        self.message = message
 
class TransitionError(Error):
    """Raised when an operation attempts a state transition that's not
    allowed.
 
    Attributes:
        previous -- state at beginning of transition
        next -- attempted new state
        message -- explanation of why the specific transition is not allowed
    """
 
    def __init__(self, previous, next, message):
        self.previous = previous
        self.next = next
        self.message = message

上面就是搞个继承自Exception类的类当基类,在扩展

1.2.4 定义清理行为

就是传说钟finally ,就是不管你有没有异常,最后必须执行的地方,会先执行,然后才会抛出异常,可以用来释放资源

这个样子

while True:
    try:
        a = int(input('test except:'))
        print(a)
        print(100/a)
    # except:
    #     print('catch error')
    #     raise
    except ZeroDivisionError as err0:
        print('Zero:', err0)
    except KeyboardInterrupt as err1:
        print('\nKey:', err1)
    except ValueError as err2:
        print('Value:',err2)
    else:
        print('happy!')
    finally:
        print('finally step;')

输出:

test except:0
0
Zero: division by zero
finally step;
test except:

else是其他异常,finally就是来兜底的

1.2.5 预定义的清理行为

这个就是with,养成好习惯,打开文件用with,就算是死也会去close
格式是这个样子

with open("myfile.txt") as f:
    for line in f:
        print(line, end="")

万能的for in,省的readline

1.2.6 断言

这个其实是一个表达是,部位真抛出断言
就这个样子:

print()
assert True
try:
    assert False
except:
    print('catch assert')
    raise

结果

catch assert
  File "D:/python/day009.py", line 45, in <module>
    assert False
AssertionError

抓的到,也抛的出

异常结构

BaseException
 +-- SystemExit
 +-- KeyboardInterrupt
 +-- GeneratorExit
 +-- Exception
      +-- StopIteration
      +-- StopAsyncIteration
      +-- ArithmeticError
      |    +-- FloatingPointError
      |    +-- OverflowError
      |    +-- ZeroDivisionError
      +-- AssertionError
      +-- AttributeError
      +-- BufferError
      +-- EOFError
      +-- ImportError
      |    +-- ModuleNotFoundError
      +-- LookupError
      |    +-- IndexError
      |    +-- KeyError
      +-- MemoryError
      +-- NameError
      |    +-- UnboundLocalError
      +-- OSError
      |    +-- BlockingIOError
      |    +-- ChildProcessError
      |    +-- ConnectionError
      |    |    +-- BrokenPipeError
      |    |    +-- ConnectionAbortedError
      |    |    +-- ConnectionRefusedError
      |    |    +-- ConnectionResetError
      |    +-- FileExistsError
      |    +-- FileNotFoundError
      |    +-- InterruptedError
      |    +-- IsADirectoryError
      |    +-- NotADirectoryError
      |    +-- PermissionError
      |    +-- ProcessLookupError
      |    +-- TimeoutError
      +-- ReferenceError
      +-- RuntimeError
      |    +-- NotImplementedError
      |    +-- RecursionError
      +-- SyntaxError
      |    +-- IndentationError
      |         +-- TabError
      +-- SystemError
      +-- TypeError
      +-- ValueError
      |    +-- UnicodeError
      |         +-- UnicodeDecodeError
      |         +-- UnicodeEncodeError
      |         +-- UnicodeTranslateError
      +-- Warning
           +-- DeprecationWarning
           +-- PendingDeprecationWarning
           +-- RuntimeWarning
           +-- SyntaxWarning
           +-- UserWarning
           +-- FutureWarning
           +-- ImportWarning
           +-- UnicodeWarning
           +-- BytesWarning
           +-- ResourceWarning

2. 标准库概览

标准库嘛,就是到哪都会有的,导入对用模块就能用
大概介绍下下面几个常用的:

  • 操作系统接口
  • 文件通配符
  • 命令行参数
  • 错误输出重定向和程序终止
  • 字符串正则匹配
  • 数学
  • 访问 互联网
  • 日期和时间
  • 数据压缩
  • 性能度量
  • 测试模块
    上面这些基本包含正常操作中都有的

2.1 操作系统接口

这个前面已经介绍过了os模块64个接口函数传送门

import os
print(os.getcwd())
print(os.listdir())
print(len(dir(os)))
# print(len(str(help(os))))

太多了,就介绍一个

D:\python
['.idea', 'day001.py', 'day002.py', 'day003.py', 'day004.py', 'day005.py', 'day006.py', 'day007.py', 'day009.py', 'test.txt', 'venv', '__pycache__']
150

那个dirhelp输出的太多了。。。

有个shutil专门做文件和目录操作


image.png

2.2 文件通配符

glob模块提供了一个函数用于从目录通配符搜索中生成文件列表:

import glob
print(glob.glob('*py'))

结果

['day001.py', 'day002.py', 'day003.py', 'day004.py', 'day005.py', 'day006.py', 'day007.py', 'day009.py']

输出个list,可以进行那种批量改名字的操作

2.3 命令行参数

通用工具脚本经常调用命令行参数。这些命令行参数以链表形式存储于sys 模块的 argv 变量。例如在命令行中执行"python demo.py one two three" 后可以得到以下输出结果:
实例:

import sys
print(sys.version_info)
print(sys.api_version)
print(sys.argv)

结果;

sys.version_info(major=3, minor=7, micro=4, releaselevel='final', serial=0)
1013
['day009.py', '1', '2', '3', '4', '5', '6', '7', 'haha']

这个之前也介绍过,敲得命令是python day009.py 1 2 3 4 5 6 7 haha
输出也是list,可以通过这种方式传配置之类的

2.4 错误输出重定向和程序终止

sys 还有 stdin,stdout 和 stderr 属性,即使在 stdout 被重定向时,后者也可以用于显示警告和错误信息。

就像这样

import  sys
sys.stderr.write('test err')
sys.exit(-100)

结果

test err
Process finished with exit code -100

这里面输出的是红色的test err 哦,用sys.exit()退出,可以选择推出返回值

2.5 字符串正则匹配

这里主要是re 模块,对于复杂的匹配和处理,正则表达式提供了简洁、优化的解决方案:
这个地方很复杂,这里简单介绍,后面专门在探索,预留传送门
大概就这么,最好直接用replace,简单粗俗

import re
test_str = 'which foot or or hand fell or fastest'
print(re.findall(r'\bf[a-z]*', test_str))
print(re.sub(r'(\b[a-z]+) \1', r'\1',test_str))
test_str = test_str.replace('or', 'replace')
print(test_str)

结果:

['foot', 'fell', 'fastest']
which foot or hand fell or fastest
which foot replace replace hand fell replace fastest

2.6 数学

2.6.1主要就是math这个模块了可以实现c实现的函数库

大概这么多:
'__doc__', '__loader__', '__name__', '__package__', '__spec__', 'acos', 'acosh', 'asin', 'asinh', 'atan', 'atan2', 'atanh', 'ceil', 'copysign', 'cos', 'cosh', 'degrees', 'e', 'erf', 'erfc', 'exp', 'expm1', 'fabs', 'factorial', 'floor', 'fmod', 'frexp', 'fsum', 'gamma', 'gcd', 'hypot', 'inf', 'isclose', 'isfinite', 'isinf', 'isnan', 'ldexp', 'lgamma', 'log', 'log10', 'log1p', 'log2', 'modf', 'nan', 'pi', 'pow', 'radians', 'remainder', 'sin', 'sinh', 'sqrt', 'tan', 'tanh', 'tau', 'trunc'
有些跟数学无关

import math
# print(dir(math))
print(math.sin(30/180*math.pi))
print(math.log(1000,10))
print(type(math.log(1000,10)))
print(int(math.log(1000,10)))

结果:

0.49999999999999994
2.9999999999999996
<class 'float'>
2

主要三角函数用弧度来计算
输出的结果都是float
不要随便强转,精度丢失很严重

2.6.2 随机数

经常用的random()

函数描述
choice(seq)从序列的元素中随机挑选一个元素,比如random.choice(range(10)),从0到9中随机挑选一个整数。
randrange ([start,] stop [,step])从指定范围内,按指定基数递增的集合中获取一个随机数,基数缺省值为1
random()随机生成下一个实数,它在[0,1)范围内。
seed([x])改变随机数生成器的种子seed。如果你不了解其原理,你不必特别去设定seed,Python会帮你选择seed。
shuffle(lst)将序列的所有元素随机排序
uniform(x, y)随机生成下一个实数,它在[x,y]范围内。

2.7 访问 互联网

主要是urlurllibsmtp(邮箱)的smtplib
这个回头好好研究下,这个这儿玩不了

2.8 日期和时间

主要是datatime 模块
主要包括下面方法
'MAXYEAR', 'MINYEAR', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'date', 'datetime', 'datetime_CAPI', 'sys', 'time', 'timedelta', 'timezone', 'tzinfo'

一些简单的操作:

import datetime
print(dir(datetime))
print(datetime.date.today())
now = datetime.date.today()
print(now.strftime("%m-%d-%y. %d %b %Y is a %A on the %d day of %B."))
birthday = datetime.date(1993,4,17)
print((now-birthday).days)

输出

['MAXYEAR', 'MINYEAR', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'date', 'datetime', 'datetime_CAPI', 'sys', 'time', 'timedelta', 'timezone', 'tzinfo']
2019-07-15
07-15-19. 15 Jul 2019 is a Monday on the 15 day of July.
9585

都是简单操作,玩细致要时间

2.9 数据压缩

以下模块直接支持通用的数据打包和压缩格式:zlibgzipbz2zipfile,以及 tarfile
压缩,解压,crc

import zlib
s = b'xxxxxxxxaaaaaaaabbbbbbbccccccc dddddd 123'
print(len(s))
t = zlib.compress(s)
print(len(t))
r = zlib.decompress(t)
print(str(r))
print(zlib.crc32(s))

结果

41
26
b'xxxxxxxxaaaaaaaabbbbbbbccccccc dddddd 123'
3693403203

2.10 性能度量

有些用户对了解解决同一问题的不同方法之间的性能差异很感兴趣。Python 提供了一个度量工具,为这些问题提供了直接答案。

from timeit import Timer
a = Timer('a = 2').timeit()
print(a)

结果:

0.012938772000000001

2.11 测试模块

doctestunittest 回头再看

文集传送门 学习python100天


整个学习python100天的目录传送门


无敌分割线


再最后面附上大神的链接
这篇跟大神无关,没有对应传送门

你或许想:《去原作者写文章的地方

「点点赞赏,手留余香」

    还没有人赞赏,快来当第一个赞赏的人吧!
0 条回复 A 作者 M 管理员
    所有的伟大,都源于一个勇敢的开始!
欢迎您,新朋友,感谢参与互动!欢迎您 {{author}},您在本站有{{commentsCount}}条评论