Python基础知识
建议有程序语言基础的童鞋阅读,零基础阅读可能会有点费解
点击下载
python最新版本
注释方法
# 单行注释
''' 多行注释 '''
数据类型
关键字
名称
示例
chr
单个字符
'', 'd'
str
字符串(多个chr)
'dd', '你好'
int
整数
1,2,3,4
float
浮点数
3.1415926
bool
布尔
Ture, False
list
列表
[1,2,3,4]
tuple
元组
('name', 'age')
dict
字典
{'name':'zzl'}
set
集合
{'zzl', 'age', 'gender'}
查看数据类型函数
type(变量)
返回该变量的数据类型
数据类型转换函数
int(num)
将num转换为整数类型
float(num)
将num转换为浮点数类型
bool(num)
将num转换为布尔类型
str(num)
将num转换为字符串类型
注:
int bool float 任何两种类型都可相互转换
任何类型都可以转换为字符串
注:
str -> int 要求全部为数字
str -> float 要求全部为数字,且可存在一个小数点
注:当布尔值False转换为str后, 在转换为bool会变成True
输入和输出
输入
语法
inp = input('提示文本')
注:输入结果为str数据类型,如须做其他操作可进行数据转换
输出
默认输出
print ( 'hello, world' )
占位符输出
print ( '名字:%s,年龄:%s,性别:%s' % ( name, age, sex) )
推荐使用
print ( f'名字:{name},年龄:{age},性别:{sex}' )
算数运算符
+ - * / ** // %
前四个同其他编程语言用法相同
**
表示平方计算
5 ** 2 === 5的2次方
//
表示做除运算后取整
%
取余运算
简写形式
+= -= *= /= **= //+ %=
注:
+
也可用于字符串拼接
*
当任意一边为字符串时,则表示重复字符串
常用运算函数
round(num, count)
表示对num四舍五入,并保留小数点后count位
比较运算符
> < >= <= = !=
常用函数
ord(chr)
返回该chr的ASCII码(只能为单个字符)
chr(num)
返回该ASCII对应的字符
逻辑运算符
and
,
or
,
not
运算符
含义
and
真真为真,其他为假(第一项为真则返回第二项的值,如第一项为假则返回第一项的值)
or
假假为假,其他为真(第一项为真,则返回第一项的值,如第一项为假,则返回第二项的值)
not
取反
成员运算符
in
,
not in
运算符
含义
示例
in
判断某字符是否存在于某字符串
'h' in 'hello'
not in
判断某字符是否不存在于某字符串
'h' not in 'hello'
分支
单分支
if bool 表达式:
print ( '执行' )
双分支
if bool 表达式:
print ( '执行语句1' )
else :
print ( '执行语句2' )
分支嵌套
if bool 表达式:
if bool 表达式2 :
print ( '执行嵌套语句' )
else :
print ( '执行语句1' )
else :
print ( '执行语句2' )
多分支
if bool 表达式1 :
print ( '执行语句1' )
elif bool 表达式2 :
print ( '执行语句2' )
elif bool 表达式. . . :
print ( '执行语句...' )
else :
print ( '如上都不满足,则执行这条语句' )
循环
循环控制
只能在循环语句中使用,只对距离最近的循环起作用
break
continue
while循环
while bool 表达式:
print ( '执行语句' )
for循环
for i in range ( 1 , 11 ) :
print ( i)
循环else结构
只有循环完整执行完毕后,才会执行else语句
当循环过程中执行break语句后,else将不执行
while bool 表达式:
print ( '执行语句' )
else :
print ( 'while else语句' )
for i in range ( 10 ) :
print ( '执行语句' )
else :
print ( 'for else语句' )
列表
对象是存储单个数据的容器,而列表(数组)就是存储多个数据的容器,任何数据类型都可以存放
# 字面量创建新列表
lst = [1,'2','三']
# 使用list函数创建新列表
lst = list([1,'2','三'])
列表的取值
通过索引下标取值
使用for循环
获取元素的下标
list.index(‘元素’)
找不到元素则抛出异常, 可预先使用in方法判断是否存在
获取列表中多个元素(切片)
list[start:end:step]
从start索引位置开始,截取到end-1位置结束,步长为step
其中step可为负值,表示从start位置往左边截取开始
start默认值为0
end默认值为列表长度
step默认值为1
省略参数但 : 必须存在
list[::]
列表的增删改操作
增加
append(item)
在原有的列表末尾添加一个元素
lst = [ 10 , 20 , 30 ]
lst. append( 100 )
print ( lst)
extend( [] )
在原有的列表末尾至少添加一个元素,添加元素必须是列表(添加多个)
lst = [ 10 , 20 , 30 ]
lst. extend( [ 99 , 100 ] )
print
( lst)
insert(index, item)
在原有的列表指定位置添加一个元素
lst = [ 10 , 20 , 30 ]
lst. insert( 1 , 99 )
print ( lst)
切片添加多个元素(指定位置添加多个元素)
使用切片把选择到的元素替换掉
lst = [ 10 , 20 , 30 ]
lst[ 1 : ] = [ 99 ]
print ( lst)
删除
remove(item)
在原有的列表删除一个元素,如果有重复元素只删除一个,如果元素不存在则抛出异常
lst = [ 10 , 20 , 30 ]
lst. remove( 20 )
print ( lst)
pop(index)
删除指定索引位置的元素,如果指定索引不存在则抛出异常
不传index,则删除末尾元素
lst = [ 10 , 20 , 30 ]
lst. pop( 1 )
print ( lst)
lst = [ 10 , 20 , 30 ]
lst. clear( )
print ( lst)
lst = [ 10 , 20 , 30 ]
lst[ 1 : ] = [ ]
print ( lst)
lst = [ 10 , 20 ,
30 ]
del lst
print ( lst)
修改
lst = [ 10 , 20 , 30 ]
lst[ 1 ] = 40
print ( lst)
lst = [ 10 , 20 , 30 ]
lst[ 1 : 3 ] = [ 40 , 50 , 60 ]
print ( lst)
列表的排序
sort()
在原列表的基础上排序
传入reserse=True降序排序
传入reserse=False生序升序
不传默认升序
lst = [ 9 , 3 , 2 , 8 ]
lst. sort( )
print ( lst)
lst = [ 9 , 3 , 2 , 8 ]
lst. sort( reserse= True )
print ( lst)
lst = [ 9 , 3 , 2 , 8 ]
lst. sort( reserse= False )
print ( lst)
sorted(lst[,rule ])
使用内置函数sorted()进行排序,将产生一个新列表对象
传入第二参数reserse=True降序排序
传入第二参数reserse=False生序升序
不传第二参数默认升序
lst = [ 9 , 3 , 2 , 8 ]
new_list = sorted ( lst)
print ( new_list)
lst = [ 9 , 3 , 2 , 8 ]
new_lsit = sorted ( lst, reserse= True )
print ( new_list)
lst = [ 9 , 3 , 2 , 8 ]
new_lsit = sorted ( lst, reserse= False )
print ( new_list)
列表生成式
[i for i in renge(1, 11)]
列表生成的表达式
lst = [ i* i for i in renge( 1 , 6 ) ]
print ( lst)
列表常用函数
len(list):列表元素个数
max(list):返回列表元素最大值
min(list):返回列表元素最小值
字典(对象)
python的内置数据结构之一,以键值对的方式存储数据。在其他语言中也叫对象。
字典的创建方式
info = {'name':'zzl', 'age':18}
info = dict(name='zzl', age=18)
字典的常用操作
info = { 'name' : 'zzl' , 'age' : 18 }
print ( info[ 'name' ] )
print ( info[ 'sex' ] )
print ( info. get( 'name' ) )
print ( info. get( 'sex' ) )
print ( info. get( 'sex' , '男' ) )
info = { 'name' : 'zzl' , 'age' : 18 }
print ( 'name' in info)
print ( 'sex' nor in info)
info = { 'name' : 'zzl' , 'age' : 18 }
del info[ 'name' ]
print ( info)
info. clear( )
print ( info)
info = { 'name' : 'zzl' , 'age' : 18 }
info[ 'sex' ] = '男'
print ( info)
info = { 'name' : 'zzl' , 'age' : 18 }
info[ 'age' ] = 20
print ( info)
获取字典的试图方法
info = { 'name' : 'zzl' , 'age' : 18 }
keys = info. keys( )
print ( keys)
values()
返回字典的所有value组成的列表
info = { 'name' : 'zzl' , 'age' : 18 }
values = info. value( )
print ( values)
items()
返回字典的所有key:value组成的列表
info = { 'name' : 'zzl' , 'age' : 18 }
itmes = info. items( )
print ( items)
字典的遍历
info = { 'name' : 'zzl' , 'age' : 18 }
for item in info:
print ( item,info[ item] )
字典的生成式
items = [ 'Fruits' , 'Books' , 'Others' ]
prices = [ 98 , 97 , 95 ]
d = { item: price for item, price in zip ( items, prices) }
print ( d)
字典的特点
字典中的所有元素都是一个key-value对,key不允许重复,value可以重复
字典中的元素是无序的
字典中的key必须是不可变对象,(即key不能为变量)
字典也可以根据需要动态的伸缩
字典会浪费较大的内存,是一种使用空间换时间的数据结构
元组
列表的另一种形式,是不可变序列
元组的创建方式
t = ( 'python' , 'world' , '20' )
t1 = tuple ( ( 'python' , 'world' , '20' ) )
t3 = ( 'python' , )
t[ 0 ]
元组的遍历
t = ( 'python' , 'world' , '20' )
for item in t:
print ( item)
注:
如果元组中对象本身是不可变对象,则不能再引用其他对象
如果元组中的对象是可变对象,则可变对象的引用不允许改变,但数据可以改变
集合
python语言提供的内置数据结构
与列表、字典都属于可变类型的序列
集合是没有value的字典
集合的存储是无序的
集合的创建
s = { 2 , 3 , 4 , 5 , 2 , 4 }
print ( s)
s1 = set ( range ( 6 ) )
print ( s1)
s2 = set ( [ 1 , 2 , 3 , 5 , 6 , 4 , 3 ] )
print ( s2)
s3 = set ( ( 1 , 23 , 5 , 32 , 1 ) )
print ( s3)
s4 = set ( 'python' )
print ( s4)
s5 = set ( { 12 , 4 , 23 , 4 , 12 } )
print ( s5)
s6 = set ( )
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
集合的常用操作
s = { 10 , 20 , 30 , 40 , 50 }
print ( 10 in s)
print ( 70 in s)
s. add( 80 )
print ( s)
s. update( { 200 , 400 } )
print ( s)
s. remove( 10 )
print ( s)
s. remove( 900 )
s. discard(
900 )
s. pop( )
s. clear( )
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
集合间的关系
两个集合是否相等(判断集合中的元素是否完全相等)
s1 = { 10 , 20 , 30 , 40 }
s2 = { 20 , 40 , 10 , 20 }
print ( s1 == s2)
print ( s1 != s2)
一个集合是否是另一个集合的子集
假如集合s1的元素里包括集合s2的全部元素,则s2是s1的子集
s1 = { 10 , 20 , 30 , 40 }
s2 = { 20 , 40 }
print ( s2. issubset( s1) )
一个集合是否是另一个集合的超集
与上相反,假如集合s1的元素里包括集合s2的全部元素,则s1是s2的超集
s1 = { 10 , 20 , 30 , 40 }
s2 = { 20 , 40 }
print ( s1. issuperset( s2) )
一个集合和另一个集合是否无交集
如果一个集合里某个元素,在另一个集合里也有存储,则两个集合有交集
s1 = { 10 , 20 , 30 , 40 }
s2 = { 80 , 60 }
print ( s1. isdisjoint( s2) )
字符串的常用操作
字符串的查询操作方法
方法名称
作用
index()
查找子串第一次出现的位置,如果查找的子串不存在时,则抛出ValueError
rindex()
查找子串最后一次出现的位置,如果查找的子串不存在时,则抛出ValueError
find()
查找子串第一次出现的位置,如果查找的子串不存在时,则返回-1
rfind()
查找子串最后一次出现的位置,如果查找的子串不存在时,则返回-1
字符串的大小写转换操作的方法
方法名称
作用
upper()
把字符串中所有字符都转成大写字母
lower()
把字符串中所有字符都转成小写字母
swapcase()
把字符串中所有大写字母转成小写字母,把所有小写字母转成大写字母
capitalize()
把第一个字符转换为大写,其余字符小写
title()
把每个单词的第一个字符转换为大写,把每个单词的剩余字符转换为小写
字符串内容对齐操作的方法
方法名称
作用
center()
居中对齐,第一个参数指定宽度,第二个参数指定填充符,第二个参数是可选的,默认是空格,如果设置宽度小于实际宽度,则返回原字符串
ljust()
左对齐,第一个参数指定宽度,第二个参数指定填充符,第二个参数是可选的,默认是空格,如果设置宽度小于实际宽度,则返回原字符串
rjust()
右对齐,第一个参数指定宽度,第二个参数指定填充符,第二个参数是可选的,默认是空格,如果设置宽度小于实际宽度,则返回原字符串
zfill()
右对齐,左边用0填充,该方法只接收一个参数,用于指定字符串的宽度,如果设置宽度小于实际宽度,则返回原字符串
字符串分割操作的方法
方法名称
作用
split(cha, max)
从字符串的左边开始分割,默认分割符是空格,返回值是一个列表,第一个参数为分割符,第二个参数为最大分割次数
split(cha, max)
从字符串的右边开始分割,默认分割符是空格,返回值是一个列表,第一个参数为分割符,第二个参数为最大分割次数
判断字符串操作的方法
方法名称
作用
isidentifier()
判断指定字符串是不是合法的标识符
isspace()
判断指定字符串是否由空白字符组成(回车、换行、水平制表符tab)
isalpha()
判断指定字符串是否全部由字母组成
isdecimal()
判断指定字符串是否全部由十进制的数字组成
isnumeric()
判断指定字符串全部由数字组成
isalnum()
判断指定字符串是否全部由字母和数字组成
字符串操作的其他方法
方法名称
作用
replace()
第1个参数指定被替换的子串
第2个参数指定替换子串的字符串
该方法返回替换后的字符串,替换前的字符串不会发生变化
该方法的第3个参数可以指定最大替换次数
cha.join(lst)
用
cha
将列表后元组的字符串合并成一个字符串。使用方法为
cha.join(lst)
字符串格式化操作
print ( '我叫%s,我今年%i岁' % ( 'zzl' , 18 ) )
print ( '我叫{0},我今年{1}岁,我真的叫{0}' . format ( 'zzl' , 18 ) )
print ( f'我叫{' zzl'},我今年{18}岁' )
字符串编码和解码操作
s = '好好学习,天天向上'
print ( s. encode( encoding=
'GBK' ) )
print ( s. encode( encoding= 'UTF-8' ) )
print ( s. encode( encoding= 'GBK' ) . decode( encoding= 'GBK' ) )
print ( s. encode( encoding= 'UTF-8' ) . decode( encoding= 'UTF-8' ) )
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
函数
函数的定义和使用
# 定义
def 函数名(a, b): # 参数a和b
函数体
return # 返回值
# 使用
函数名()
# 代码演示
def cals(a, b):
c = a + b
return c
res = cals(20, 30) # 50
函数的参数传递
位置传参,
cals(20, 30)
,此时a的值是20, b的值是30
关键字传参,
cals(b=70, a=30)
此时a的值是30, b的值是70
函数的返回值
如果函数没有返回值(函数执行完毕之后,不需要给调用处提供数据),return可以省略不写
函数的返回值,如果是1个,直接返回原值
函数的返回值,如果是多个,返回的结果为元组
def fun ( lst) :
odd = [ ]
even = [ ]
for i in lst:
if ( i% 2 ) :
odd. append( i)
else :
even. append( i)
return odd, even
lst = [ 10 , 23 , 65 , 78 , 32 , 77 ]
print ( fun( lst) )
函数的默认值
在定义函数的时候,可以给形参赋上默认值,当没传参数的时候,函数会取默认值,如果传参和默认值同时存在,传的参数会替换掉默认值
def cals ( a, b = 10 ) :
c = a + b
return c
res = cals( 20 )
res = cals( 20 , 30 )
函数的参数定义
个数可变的位置参数
定义函数时,可能无法确定传递的实参个数,这个时候就要使用可变的位置形参。使用*定义,结果为一个元组
def fun ( * args) ;
print ( args)
fun( 1 )
fun( 1 , 2 , 3 )
个数可变的关键字参数(指定参数名传递参数)
定义函数时,可能无法确定传递的关键字实参个数,这个时候就要使用可变的关键字形参。使用*定义,结果为一个字典
def fun ( ** args) ;
print ( args)
fun( a= 10 )
fun( a= 10 , b= 20 , c= 30 )
以上参数在函数定义时,一种方式只能定义一次。
当两种参数定义方式同时存在时,位置形参必须在关键字形参前面
python异常处理机制
异常捕获
try :
可能出现异常的语句放在这里
except 你要捕获的异常类型:
捕获到异常后你想做什么
except 你要捕获的异常类型:
捕获到异常后你想做什么
. . .
except BaseException as e:
print ( '出错了' , e)
print ( '程序照常执行' )
异常捕获else
try :
可能出现异常的语句放在这里
except 你要捕获的异常类型:
捕获到异常后你想做什么
except 你要捕获的异常类型:
捕获到异常后你想做什么
. . .
except BaseException as e:
print ( '出错了' , e)
else :
print ( '如果没有异常则执行else部分'
)
try…except…else…finally结构
try :
a = int ( input ( '请输入第一个整数' ) )
b = int ( input ( '请输入另一个整数' ) )
res = a/ b
except BaseException as e:
print ( '出错了' , e)
else :
print ( '结果为:' res)
finlly:
print ( '无论是否产生异常,总会被执行的代码' )
python常见的异常类型
异常类型
描述
ZeroDivisionError
除零or向零取余
IndexError
序列中没有此索引
KeyError
映射中没有这个键
NameError
未声明or未定义
SyntaxError
语法错误
ValueError
传入无效的参数
类与对象
类的创建
类属性: 类中方法外的变量称为类属性,被该类的所有实例对象共享
类方法: 使用
@classmethod
修饰的方法,可使用类名直接访问
静态方法: 使用
@staticmethod
修饰的方法,可使用类名直接访问
class Student :
native_pace = '河南'
def __init__ ( self, name , age) :
self. name = name
self. age = age
def eat ( self) :
print ( '吃饭' )
@staticmethod
def method ( ) :
print ( '使用staticmethod进行修饰,所以我是静态方法' )
@classmethod
def cm ( cls) :
print ( '使用calssmethod进行修饰,所以我是类方法' )
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
类实例对象
stu1 = Student( 'zzl' , 18 )
print ( stu1. name)
print ( stu1. age)
stu1. eat( )
动态绑定属性和方法
stu = Student( 'zzl' , 18 )
stu. gender = '男'
print ( stu. gender)
def show ( ) :
print ( 'show方法执行' )
stu. show = show
stu. show( )
面向对象的三大特征
代码演示
# 继承
class Person(object):
def __init__(self, name, age):
self.name = name
self.age = age
def info(self):
print(self.name, self.age)
class Student(Person):
def __init__(self, name, age, stu_no):
super().__init__(name, age)
self.stu_no = stu_no
class Teacher(Person):
def __init__(self, name, age, teachofyear):
super().__init__(name, age)
self.teachofyear = teachofyear
stu = Student('张三', 20, 10001)
teacher = Teacher('李四', 35, 10)
stu.info() # 张三 20
teacher.info() # 李四 35
# python 支持多继承
class A(class1, class2):
pass
# 方法重写
# 方法重写就是在子类里定义与父类重名的方法,这样就会优先调用子类的定义的方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 1 2 3 4 5 6 7 8 9 10 11
12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
模块和包
定义:每一个.py文件就是一个模块
使用模块化的好处
方便其他程序和脚本的导入使用
避免函数名和变量名冲突
提高代码的可维护性
提高代码的可重用性
导入模块
import 模块名称 [ as 别名]
from 模块名称 import 函数/ 变量/ 类
包
包是一个分层次的目录结构,它将一组功能相近的模块组织在一个目录下
作用
代码规范
避免模块名称冲突
包与目录的区别
包含__init__.py文件的目录称为包
目录里通常不存在__init__.py文件
包的导入
import 包名.模块名
文件的读写
内置函数open()创建文件对象
file = open ( 'a.txt' , 'r' )
print ( file . readlines( ) )
file . close( )
常用的文件打开模式
打开模式
描述
r
以只读模式打开文件,文件的指针将会放在文件的开头
w
以只写模式打开文件,如果文件不存在则创建,如果文件存在,则覆盖原有内容,文件指针在文件的开头
a
以追加模式打开文件,如果文件不存在则创建,文件指针在文件开头,如果文件存在,则在文件末尾追加内容
b
以二进制方式打开文件,不能单独使用,需要与其他模式一起使用,rb,后者wb
+
以读写方式打开文件,不能单独使用,需要与其他模式一起使用,如a+
文件对象的常用方法
方法名
描述
read([size])
从文件中读取size个字节或字符的内容返回,若省略size,则读取到文件末尾,即一次读取文件所有内容
readline()
从文本文件中读取一行内容
readlines()
把文本文件中每一行都作为独立的字符串对象,并将这些对象放入列表返回
write(str)
将字符串str内容写入文件
writelines(s_list)
将字符串列表s_list写入文本文件,不添加换行符
seek(offset[, whence])
把文件指针移动到新的位置,offset表示相对与whence的位置:
offset:为正则往结束方向移动,为负则往开始方向移动
whence不同的值代表不同含义:
0:从文件头开始计算(默认值)
1:从当前位置开始计算
2:从文件末尾开始计算
tell()
返回文件指针的当前位置
flush()
把缓冲区的内容写入文件,但不关闭文件
close()
把缓冲区的内容写入文件,同时关闭文件,释放文件对象相关资源
with语句(上下文管理器)
with语句可以自动管理上下文资源,不论什么原因跳出with语句都能确保文件正确的关闭,以此来达到释放资源的目的
with open ( filename, mode) as file :
pass
目录操作 (os 和 os.path)
os模块是python内置的与操作系统功能和文件系统相关的模块,该模块中的语句的执行结果通常与操作系统有关,在不同的操作系统上运行,得到的结果可能不一样
os模块与os.path模块用于对目录或文件进行操作
import os
os. system( 'calc.exe' )
os. system( 'notepad.exe' )
os. startfile( '路径' )
os模块操作目录相关函数
函数
说明
getcwd()
返回当前的工作目录
listdir(path)
返回指定路径下的文件和目录信息
mkdir(path[, mode])
创建目录
makedirs(path1/path2…[, mode])
创建多级目录
rmdir(path)
删除目录
removedirs(path1/path2…)
删除多级目录
chdir(path)
将path设置为当前工作目录
os.path模块操作目录相关函数
函数
说明
abspath(path)
用于获取文件或目录的绝对路径
exists(path)
用于判断文件或目录是否存在,如果存在返回True,否则返回False
join(path, name)
将目录与目录,或者目录与文件名连接起来
split(path)
分离目录和文件名
splittext(name)
分离文件名和扩展名
basename(path)
从一个目录中提取文件名
dirname(path)
从一个路径中提取文件路径,不包括文件名
isdir(path)
判断是否为路径
python内置模块
使用
import
关键字引入
模块
描述
random
随机数生成
traceback
处理异常
sys
与python解释器及环境操作相关的标准库
time
提供与时间相关的各种函数的标准库
os
提供了访问操作系统服务功能的标准库
calendar
提供与日期相关的各种函数的标准库
urllib
用于读取来自网上(服务器)数据的标准库
json
用于使用JSON序列化和反序列化对象
re
用于在字符串中执行正则表达式匹配和替换
math
提供标准算术运算函数的标准库
decimal
用于进行精准控制运算精度、有效数位和四舍五入操作的十进制运算
logging
提供了灵活的记录事件、错误、警告和调试信息等日志信息的功能