补充知识点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
那个
dir
和help
输出的太多了。。。
有个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 访问 互联网
主要是
url
的urllib
和smtp
(邮箱)的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 数据压缩
以下模块直接支持通用的数据打包和压缩格式:
zlib
,gzip
,bz2
,zipfile
,以及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 测试模块
doctest
和unittest
回头再看
文集传送门 学习python100天
整个学习python100天的目录传送门
无敌分割线
再最后面附上大神的链接
这篇跟大神无关,没有对应传送门
网友评论