2024年网络安全最新Python详细介绍及使用(基础篇)

%号的用法:%namewidthtypecode

[]表示可选修饰符

-:表示左对齐,默认右对齐

+:表示包含数字符号,正数也会带正号

0:表示以0填充



dic={‘x’:32,‘y’:27.490325,‘z’:65}

print(‘%(x)-10d %(y)0.3f %(z).3f’ %dic) #注:x左对齐最小宽度10y最小宽度0小数点精确到三位

32         27.490 65.000

‘%#X’ % 108  #注:将108转换成无符号的16进制,前面显示0X

‘0X6C’

“%x %s %d” %(108,“abc”,3)

‘6c abc 3’

‘%.2f’ % 1234.567890  #注:显示小数点后两位数

‘1234.57’

“MM/DD/YY = %02d/%02d/%d” % (1, 18, 17)

‘MM/DD/YY = 01/18/17’


注:说明--02d 表示此位填充的是十进制的整数,且为两位,若只有一位则前面添0。


### ****5、字符串内建函数****




|  |  |
| --- | --- |
| 常用方法 | 描述 |
| s.captitalize() | 首字符变大写 |
| s.center(width) | 返回一个字符串居中,并使用空格填充值长度width |
| s.count(str[,star,end]) | 指定范围内str出现的次数 |
| s.decode([encoding[,errors]) | 以encoding指定的编码格式解码str,如果出错默认报ValueError异常,除非error指定的是’ignore’或者’replace’ |
| s.encode([encoding[,errors]) | 以encoding指定的编码格式编码str,如果出错默认报ValueError异常,除非error指定的是’ignore’或者’replace’ |
| s.endwith(suffix[, start[, end]) | 检查字符串是否已suffix后缀结尾,返回bool类型 |
| s.find(sub [,start [,end]]) | 检测sub是否包含在字符串中,如果是返回开始的索引,如果不是则返回-1 |
| s.index(sub [,start[,end]]) | 找到指定字符串sub首次出现的位置,否则报错 |
| S.isdigit() | 字符串中值包含数字则返回True,否则返回False |
| s.join(t) | 将s作为分隔符,连接序列t中的字符串 |
| s.lower() | 转换为小写形式 |
| S.replace(old,new [,maxreplace] | 替换一个字符串 |
| s.split([sep [,maxsplit]]) | 将sep作为分隔符对字符串进行划分,maxsplit是划分的最大次数 |
| s.strip([chrs]) | 删掉chrs开头和结尾的空白或chrs字符 |
| s.upper() | 将一个字符串转换为答谢形式 |


### 6、扩展:****python中的编码问题****


**前面我们说过:****python2.x中的系统缺省编码为ascii,Python3.x中的系统缺省编码为utf-8**


#### ****6.1、python中编码设置介绍****


    系统的缺省编码(一般就是ascii):sys.getdefaultencoding()


    系统当前的编码:locale.getdefaultlocale()


    文件系统的编码:sys.getfilesystemencoding()


    终端的输入编码:sys.stdin.encoding


    终端的输出编码:sys.stdout.encoding


    代码的缺省编码:文件头上# -\*- coding: utf-8 –\*-


    系统缺省的编码(sys.getdefaultencoding()):python2.x默认源代码文件是ascii编码,这个缺省编码在Python转换字符串时用的到。首先明白,一个文件以某种编码格式保存后,str存储的字节流就是这种编码格式对应的字符编码。Python3.x中的系统缺省编码为utf-8,python3.x中的str默认是unicode编码,系统编码采用utf-8便捷。


例如:


![](https://img-blog.csdnimg.cn/20210519231237435.png)![](https://img-blog.csdnimg.cn/20210519231255508.png)


****情况一:缺省头部声明****


#源文件以GBK保存,你好-对应的字符编码:\xc4\xe3\xba\xc3


****Python2.x中:****


str1='你好,python' #以实际保存的编码存储:'\xc4\xe3\xba\xc3,python'


print str1    


   当载入这个.py程序的时候,python2.x试图去解析这个字节流,这是没有头文件声明,就按默认系统缺省编码(ascii)读取源码,当读到第一行时发现以ascii编码无法解析出中文对应的编码'\xc4\xe3\xba\xc3'。因此报以下错误:SyntaxError: Non-ASCII character '\xc4'。


****Python3.x中:****


str1='你好,python' #以实际保存的编码存储:'\xc4\xe3\xba\xc3,python'


print(str1)


    当载入这个.py程序的时候,python3.x试图去解析这个字节流,这是没有头文件声明,就按默认系统缺省编码(UTF-8)读取源码'\xc4\xe3\xba\xc3,python'。UTF-8中找不到对应的编码,因此报以下错误:SyntaxError: Non-UTF-8 character '\xc4'。


****情况二:头部声明与存储格式不一致****(注:文件实际保存GBK,头部声明为utf-8)


****Python2.x中:****


#--\*--coding:utf-8--\*--


str1='你好,python'


print str1


报错:UnicodeDecodeError: 'utf8' codec can't decode byte 0xc4 in position 0: invalid continuation byte。文件实际存储的GBK的编码,而我们在头部声明了编码,当python解释器读取源代码时,没有声明读取方式则系统的缺省编码读取,声明了则按头部声明读取,而我们保存的GBK一个中文两个字节,而UTF-8一个中文要三个字节,并且UTF-8是有BOM的,头部和声明不一致,可能导致乱码,甚至会出现编码错误,此处就出现编码错误。


****Python3.x中:****


#--\*--coding:utf-8--\*--


str1='你好,python'


print(str1)


报错:SyntaxError: (unicode error) 'utf-8' codec can't decode byte 0xc4 in position 0:invalid continuation byte。原因与上同。


    注:代码的缺省编码(# -\*- coding: utf-8 –\*-):是一个.py文件解析时的编码格式。即,以一种编码保存后,之后python解释器读取源文件的时候,要按照一定的编码去读取源码文件。解析文件的时候遇到的str都会以此编码进行解析。所以要尽量保证保存时文件的编码格式要和声明的编码格式一致。


****系统当前的编码(locale.getdefaultlocale())****:用于查看运行环境windows/Unix/Linux系统的编码,易于实现国际化。



import locale

locale.getdefaultlocale()#注:查看系统当前的字符编码,cp936代表的GBK编码

(‘zh_CN’, ‘cp936’)


****文件系统的编码(sys.getfilesystemencoding()):****



sys.getfilesystemencoding()  #python2.x中

‘mbcs’

sys.getfilesystemencoding() #python3.x中

‘utf-8’


****终端的输入编码(sys.stdin.encoding):****



sys.stdin.encoding

‘cp936’


****终端的输出编码(sys.stdout.encoding):****



sys.stdout.encoding

‘cp936’


注:这里的终端大概指的是运行环境,DOS上运行输出始终和系统设置语言一样是GBK,而PyCharm里的输入输出编码因其设置而不同。


#### ****6.2、python2.x字符编码问题****


    在python2.x中,使用unicode类型作为编码的基础类型,编解码要以其为中间形式过渡,即进行str和unicode之间的转换。


    解码然后再编码的过程,即:****str->unicode->str****的过程。中间得到的叫做unicode对象。这里需要强调的是unicode是一种字符编码方法,是“与存储无关的表示”,而utf8是一种以unicode进行编码的计算机二进制表示,或者说传输规范。


****str->unicode->str:str字符串是原字符串使用特定的编码方式得到的字节流,如果知道了该编码方式,就可以使用decode(解码)函数把str字节流解码为原字符串的Unicode对象。****方式:


str\_obj.decode(‘字符编码’)


unicode(str\_obj,‘字符编码’)


****而unicode对象也可以使用encode(编码)函数编码为对应的字节流。方式:********uniocde\_obj.encode(‘字符编码’)****


例如:unicode对象编码过程



sys.stdout.encoding

‘cp936’

str1=‘你好’

str1

‘\xc4\xe3\xba\xc3’

str1.decode(‘GBK’)  #将字节序列解码为unicode对象

u’\u4f60\u597d’

print str1.decode(‘GBK’) #说明一

你好

str_u=u’你好’

print str_u      #Unicode对象

你好

print str_u.encode(‘GBK’)   #GBK字节流

你好

print str_u.encode(‘UTF-8’) #UTF-8字节流 #说明二

浣犲ソ


注:说明一:实际上print 语句输出unicode对象时会默认使用sys.stdout.encoding编码转换。str1.decode('GBK')转为unicode对象后,如果没有显示的进行解码,系统会默认使用str1.decode('GBK').encoding(sys.stdout.encoding)说明二:如果显示的指定了编码,此时就转为str对象,就不会为我们进行编码。


例如:str解码为unicode对象    



import sys

sys.stdout.encoding

‘cp936’

sys.getdefaultencoding()

‘ascii’

str1=‘你好’

str1.decode(‘gbk’)

u’\u4f60\u597d’

print str1.decode(‘gbk’)  #说明一

你好

str1.encode(‘gbk’)    #说明二

Traceback (most recent call last):

file “<pyshell#3>”, line 1, in

str1.encode(‘gbk’)

UnicodeDecodeError: ‘ascii’ codec can’t decode byte 0xc4 in position 0: ordinal not in range(128)


    #注:说明一:将str字节流解码后得到是unicode对象,再使用print语句就回到了上面案例的过程中。


    说明二:如果我们直接对str字节流进行编码,没有显示的先进行解码,那么系统就会为我们先解码为unicode对象。即:str1.decode(sys.getdefaultencoding())。因为此时默认的系统编码就是ascii,所以会报这个错误。但是这个问题是可以解决的。方式如下:



import sys

reload(sys)

sys.setdefaultencoding(‘gbk’)


注:不要试图在IDLE中运行:这会出现BUG,运行后我们就不能输出了。在DOS中的默认编码是GBK,在DOS中运行.py程序使用print语句应该注意这个问题。在对字节流进行encode(编码)前会默认使用默认编码先进行一次decode(解码)


#### ****6.3、python2.x解决字符编码问题的方法****


    方式一:


    最好的方式都使用unicode对象。将所有的str字节流都解码成unicode,不去混用str和unicode对象。程序内部均使用unicode,而输出的时候,则尽早将其编码成字节流。


或者可以使用:设置 Sublime Text 的 Python Build System 环境变量


    方式二:



import sys
reload(sys)
sys.setdefaultencoding(‘utf-8’)


  注:修改默认编码,这种方法虽然可以,但是可能会导致一些奇怪的问题。优先使用前一种方法。


#### **6.4、python3.x中的字符编码问题**


    在python3.x中,使用str类型作为编码的基础类型,编解码要以其为中间形式过渡,即进行bytes和unicode之间的转换。


    解码然后再编码的过程,即:****bytes********->str(unicode)->bytes****的过程。中间得str字符串(unicode字符串)。


****str->unicode->str:str字符串是unicode字符串,内置了encode()方法将其编码为对应的bytes类型的字节序列。而bytes字节类型内置了decode()方法将其解码为str字符串。****


    **方式:str.encode     -> bytes    bytes.decode   -> str**


例如:



str1=‘你好,python’

str1.encode(‘gbk’)

b’\xc4\xe3\xba\xc3,python’

str2=str1.encode(‘gbk’)

str2.decode(‘gbk’)

‘你好,python’


#### **6.5、python2.x与python3.x中的字符串异同**




|  |  |  |
| --- | --- | --- |
| python2.x中的str  | Python3.x中的str | 异同 |
|  工厂函数: str(object='')-> str   | 工厂函数: str(object='') -> str str(bytes\_or\_buffer[, encoding[, errors]]) -> str | python2.x中str返回字节序列.字符串和字节序列混为一谈。而python3.x返回的是unicode字符串。而把二进制明确的归为bytes类型。 |
| str.encode() str.decode() | str.encode() [bytes.decode()] | python2.x中str内置了编码解码方法,而python3.x中str只有解码方法。 |
| Python3.x中str就是unicode字符串,而不再使用unicode对象了。 |


## ****三、序列-列表类型****


### ****1、列表概述****


   列表元素用中括号[ ]包裹,可包裹任意对象的有序几集合,通过索引访问其中的元素,元素的个数及元素的值可以改变(****可变类型****)。



列表的定义格式:

li=[] 或者 li=list() #创建一个空列表

li=[…] 或者 li=list(iterable)


例如:



li=[]

li=[1,2,3]

list()

[]

list(‘abc’)

[‘a’, ‘b’, ‘c’]

list((1,2,3))

[1, 2, 3]


### ****2、列表操作****


#### **2.1、访问列表元素**



方式一:索引,列表也是序列。

方式二:迭代,序列都支持迭代。


例如:



l1=[‘a’,‘b’,‘c’,‘d’]

l1[1]

‘b’

for item in l1:

print(item)

a

b

c

d


#### **2.2、更新列表元素**



方式一:根据索引

方式二:使用append方法


例如:    



l1[0]=1

l1

[1, ‘b’, ‘c’, ‘d’]

l1.append(‘e’)

l1

[1, ‘b’, ‘c’, ‘d’, ‘e’]


#### **2.3、删除列表元素**



方式一:使用del操作符

方式二:使用remove()方法


例如:



del l1[0]

l1

[‘b’, ‘c’, ‘d’, ‘e’]

l1.remove(‘e’)

l1

[‘b’, ‘c’, ‘d’]


#### **2.4、比较列表大小**


例如:



l1=[‘a’,‘b’,‘c’]

l2=[‘a’,‘c’,‘b’]

l1==l2

False

l1<l2

True


注:列表比较大小,会将两个列表的元素依次比较,直到有一方的元素胜出,就得出结果了。


### ****3、列表常用函数****




|  |
| --- |
| 序列函数 |
| 函数 | 描述 |
| len(list) | 列表的元素 |
| max(list)/min(list) | 最大元素/最小元素 |
| sorted(list)/reversed(list) | 排序(小到大)/倒叙(颠倒元素) |
| enumerate(list)/zip(list1 [,list2]) | 遍历方式 |
| sum(list) | 求一个列表中的总值(纯数字列表) |
| 列表内建函数 |
| append(obj) | 向列表中添加一个对象obj |
| count(obj) | 返回指定元素在列表中出现的次数 |
| extend(iterable) | 通过迭代的方式添加元素,要添加的元素是支持迭代的序列,无返回值,直接对原列表进行修改 |
| index(value,[start, [stop]]) | 返回指定元素的索引 |
| pop([index]) | 弹出(删除)元素不写索引默认最后一位,返回弹出的元素 |
| remove(value) | 删除指定元素,不存在则报错 |
| reverse() | 将列表逆序排列,无返回值,直接对原列表进行修改 |
| sort() | 对列表进行排序,无返回值,直接对原列表进行修改 |


例如:



l1=[‘a’,‘b’,‘c’]

for i,item in enumerate(l1):

print 1,item

1 a

1 b

1 c

l2=[1,2,3]

for i,j in zip(l1,l2):

print ‘%s %s’ %(i,j)

a 1

b 2

c 3


## 四、序列-元祖类型


### ****1、元组概述****


    元组元素用小括号( )包裹,不可变对象。不可以更改(但不意味着,里面包含的可变对象不可更改)。元组可以看成是只读的列表。



元组的定义格式:

atuple=() 或 atuple=tuple()   #创建空元组

atuple(a,b,c) 或 atuple((iterable) #创建元组


注:也可以不带()创建,即:atuple=1,2,3,4...


例如:  



>>> aTuple =(‘robots’,77,88,‘try’)

>>> aTuple

(‘robots’, 77, 88, ‘try’)

>>> aTuple[1]=5  #注:TypeError不支持修改

Traceback (most recent call last):

file “<pyshell#208>”, line 1, in

aTuple[1]=5

TypeError: ‘tuple’ object does not support item assignment

t=123,456,789,‘hello’

t

(123, 456, 789, ‘hello’)

t2=(1,2,[3,4])

t2[2][0]=‘a’

t2

(1, 2, [‘a’, 4])

(‘3’)#试图创建一个元素元组的时候,没逗号外部的()会被当做分隔符

‘3’

(‘3’,)   #记得加上一个逗号,表明()不是分隔符

(‘3’,)


   #注:元组在输出时总是有括号的,以便于表达式嵌套结构。在输入时可能有或没有括号都可以。虽然元组本身不可变,但是如果元组内嵌套了可变类型的元素,那么此类元素的修改不会返回新的元组。


### ****2、元组的操作及函数****




|  |  |
| --- | --- |
| 常用方法 | 描述 |
| count(value) | 返回指定元素出现的次数 |
| index(value [start, [stop]]) | 返回指定元素的索引 |


## ****五、字典(映射)类型****


### ****1、字典概述****


    字典在其他语言中又被称作关联数组或散列表。字典是 Python 中的映射数据类型,由键-值(key-value)对构成。


    序列是以连续的整数为索引,与此不同的是,字典以关键字为索引,关键字可以是任意不可变类型,通常用字符串或数值。如果元组中只包含字符串和数字,它可以做为关键字,如果它直接或间接的包含了可变对象,就不能当做key键值。不能用列表做关键字,因为列表可以用它们的append() 和 extend()方法,或者用切片、或者通过检索变量来即时改变。值可以是任意类型的 Python 对象,字典元素用大括号{ }包裹。



字典的定义格式:

d= {}  #空字典

d1={key1:value1,key2:value2,…}

链表中存储关键字-值对元组的话,字典可以从中直接构造:

d2=dict([(‘x’,’y’),(…)])    或    dict(zip(‘xyz’,’123’)


    注:字典中的键必须是可哈希的。所有的不可变类型都是可哈希的,因此他们可以作为字典的键。一个键只能对应一个值,字典键重复赋值,只取最后的。


    注:哈希表是一种数据结构,哈希表的算法是获取键,对键执行一个叫做哈希函数的操作,并根据计算的结果(一定的算法,算出下标),选择在数据结构的某个地址来存储对应的值。任何一个值的存储,取决于它的键。所以哈希表中的值是没有顺序的。


### ****2、映射类型操作符****




|  |  |
| --- | --- |
| 操作符/函数 | 描述 |
| [] | 字典键查找操作符,d[k] -->value |
| in / not in | 成员关系操作符,判断是否存在某个key值 |
| len(d) | 返回字典的长度 |
| cmp(d1,d2) | 比较两个字典的大小,从左往右,一项比,先比较第一项key值,相同则比较value值 |
| hash(obj) | 返回obj的哈希值,对象不可哈希,则报错 |


### ****3、字典的内建函数****




|  |  |
| --- | --- |
| 常用方法 | 描述 |
| **clear()** | **清空字典中所有元素** |
| **copy()** | **浅复制该字典,返回字典的一个副本** |
| **formkeys(seq[,val])** | **创建一个字典使用seq中的元素作为key值,无val,value默认为None** |
| **get(key[,d])** | **返回key对应的value值,如无此key值则返回d,d不写默认为None** |
| has\_key(k) | 判断有无Key,有则返回True,无则返回False |
| **items()** | **Python3.x中相当于python2.x中的viewitems(),可以使用lits(dict.items)-->list   [(‘’,’’),...(‘’,’’)]** **python2.x返回返回二维元组的list   [(‘’,’’),...(‘’,’’)]** |
| iteritems() | 返回一个迭代器对象,包含每一项(k,v) |
| iterkeys() | 返回一个迭代器对象,包含每一项key值 |
| itervalues() | 返回一个迭代器对象,包含每一项value值 |
| keys() | Python3.x中相当于python2.x中的viewkeys() Python2.x返回key的list    -->[key1,key2...] |
| **pop(k[,d])** | **删除一个具体的key,返回该key值对应的value,未找到对应的key报错** |
| **popitem()** | **随机删除一个键值对,返回该键值对的二维元组** |
| **setdefault(k[,d])** | **如果存在key值,就返回对应的value,如果不存在key值,就在字典中添加一个键值,key:d,如果d不写,默认是None** |
| **update([E, ]\*\*F)** | **更新一个字典,如果有相同的key,则更新value,如果没有则插入键值。例如:>>> d2={'a':1} >>> d3={'a':'a','b':2} >>> d2.update(d3)>>> print d2  {'a': 'a', 'b': 2}** |
| **values()** | **返回value的list   -->> [value1,value2...]** |
| viewitems() | dict\_items([(key1, value1), (key2, value2)...) |
| viewkeys() | dict\_keys([key1, key2...]) |
| viewvalues() | dict\_keys([value2, value2...]) |
| 注:灰色的是python2.x中存在的方法,python3.x中已经没有了 |


例如:



aDict = {‘localhost’: ‘127.0.0.1’} #创建字典

aDict[‘port’] = 80 #添加数据

aDict

{‘port’: 80, ‘localhost’: ‘127.0.0.1’}

aDict.keys()  #注:获取字典中所有的key值

[‘port’, ‘localhost’]

aDict[‘port’]  #注:获取key对应的value值

80

for key in aDict: print(key,aDict[key]) #注:遍历字典

port 80

localhost 127.0.0.1

del aDict[‘port’]

aDict

{‘localhost’: ‘127.0.0.1’}


**注:字典和列表的区别**


    无论dict有10个元素还是10万个元素,查找速度都一样。而list的查找速度随着元素增加而逐渐下降。不过dict的查找速度快不是没有代价的,dict的缺点是占用内存大,还会浪费很多内容,list正好相反,占用内存小,但是查找速度相对dict慢。


### ****4、扩展-浅拷贝和深度拷贝****


   拷贝可分为浅拷贝和深度拷贝


   浅拷贝:只拷贝父对象,不会拷贝对象的内部的子对象


   深度拷贝:拷贝对象及其子对象


例如:



import copy

a=[1,[2,3],4]

b=a

c=copy.copy(a)       #注:浅拷贝

d=copy.deepcopy(a)   #注:深度拷贝

print(id(a),id(b),id©,id(d))

50068872 50068872 50011336 50074824

#说明:=是赋值操作,直接将b指向了a的引用,都指向同一块内存地址。

#copy()操作和deepcopy()操作的id都已发生变化了。即c、d指向的内存地址发生改变了。

a.append(5)   #注:对a进行修改

print(a,b,c,d)   #注:因为a、b都指向的是一片内存地址对a修改b自然受到影响

[1, [2, 3], 4, 5] [1, [2, 3], 4, 5] [1, [2, 3], 4] [1, [2, 3], 4]

a[1].append(6) #注:对内部子对象进行修改

print(a,b,c,d)  #注:a、b、c都发生改变了,只有深度拷贝内部子对象没有受到影响

[1, [2, 3, 6], 4, 5] [1, [2, 3, 6], 4, 5] [1, [2, 3, 6], 4] [1, [2, 3], 4]


注:列表和字典都支持两种类型的复制操作:浅拷贝和深度拷贝。深度拷贝可使用copy模块中的deepcopy()实现。


## ****六、集合类型****


### ****1、集合概述****


   集合对象****是一组无序排列的可哈希的值****。集合成员可以做字典中的键。


   dict的作用是建立一组key和一组value的映射关系,dict的key是不能重复的。有的时候,我们只想要dict的key,不关心 key 对应的 value,目的就是保证这个集合的元素不会重复,这时,set就派上用场了。set 持有一系列元素,这一点和 list 很像,但是set的元素没有重复,而且是无序的,这点和 dict 的 key很像。集合有两种不同的类型:可变集合(set)和不可变集合(frozenset)。


   对于集合set对象来说,是可变集合,是不可哈希的,因此set对象不能作为字典的键,但是它里面的元素可以。而对于frozenset对象来说,是不可变集合,它是可哈希的,能被作为字典的键。



可变集合set定义语法:

s=set()  #创建一个空集合

s=set(iterable) #通过一个可迭代对象创建,里面的元素必须是可哈希的

不可变集合frozenset定义语法:

s=frozenset()  #创建一个空集合

s=frozenset(iterable)



例如:

l1=[1,2,3,3,2,1]

set(l1)

set([1, 2, 3])

l2=[l1,2,3,4]

set(l2)    #注:可迭代序列l2中包含了不可哈希元素

Traceback (most recent call last):

file “<pyshell#3>”, line 1, in

set(l2)

TypeError: unhashable type: ‘list’


### 2、****集合类型的操作符****




|  |  |
| --- | --- |
| 操作符/函数 | 描述 |
| in / not in | 判断是否是成员关系 |
| ==/!= | 等于/不等于 |
| s < t | s是t的(严格)子集 |
| s > t | s是t的(严格)超集 |
| s >= t | s是t的(非严格)超集 |
| s & t | s 和t的交集 |
| s | t | s和t的合集 |
| s - t | 差集 |
| s ^ t | 对称差集 |
| len() | 集合中的项数 |


### ****3、可变集合set的内建函数****




|  |  |
| --- | --- |
| 方法/操作 | 描述 |
| add(...) | 添加一个元素到s集合中 |
| clear() | 清空集合项 |
| copy() | 浅复制一个s集合的副本 |
| difference(t) | 求差集,返回所有在s中但不在t中的项(不会改变s) |
| difference\_update(t) | 求差集,直接移除s中在t中也出现的项,默认返回None(改变原有集合s) |
| discard(...) | 移除一个元素,如果存在就移除,不存在就不做什么 |
| intersection(t) | 求交集,返回所有在s和t中的项目 |
| intersection\_update(t) | 求交集,直接更新s集合作为交集,默认返回None(改变原有集合s) |
| isdisjoint(t) | 如果s和t没有相同项,则返回True |
| issubset(t) | 如果s是t的一个子集,则返回True |
| issuperset(t) | 如果s是t的一个超集,则返回True |
| pop() | 随机移除一个元素,没有元素移除将会报错 |
| remove(...) | 移除set集合中的一个元素,如果不存在这个元素就会报错 |
| symmetric\_difference(t) | 求对称差集,返回所有在s或t中,但又不同时在这两个集合中的项(不会改变原有集合s) |
| symmetric\_difference\_update(t) | 求对称差集,s集合会变更为对称差集(会改变原有集合s) |
| union(t) | 求并集,返回所有在s或t中的项(不会改变原集合s) |
| update(t) | 求并集,更新s集合为新的s和t的并集(会改变原集合s) |


### ****4、不可变集合frozenset的内建函数****




|  |  |
| --- | --- |
| 方法/操作 | 描述 |
| copy() | 浅复制一个s集合的副本 |
| difference(t) | 求差集,返回所有在s中但不在t中的项(不会改变s) |
| intersection(t) | 求交集,返回所有在s和t中的项目 |
| isdisjoint(t) | 如果s和t没有相同项,则返回True |
| issubset(t) | 如果s是t的一个子集,则返回True |
| issuperset(t) | 如果s是t的一个超集,则返回True |
| symmetric\_difference(t) | 求对称差集,返回所有在s或t中,但又不同时在这两个集合中的项(不会改变原有集合s) |
| union(t) | 求并集,返回所有在s或t中的项(不会改变原集合s) |


## ****第三章 python中的语句或表达式****


## ****一、基本概述****


### ****1、语句****


     语句,是程序中最小的独立单元,通常以行为单位。语句可以包含表达式,表达式也可以单独形成一个语句。(语句最明显的标志为分号结束。但并不是什么时候都会有分号,一条语句独占一行时可以不写分号)。


    Python中的常见语句:


    赋值语句:简单赋值(=)、多重赋值(x1=x2=3)、增强赋值(+=、-=...)


    调用:执行函数(打印语句:print,python2.x中是语句,python3.x中已是函数)


    条件判断语句:if/elif/else;


    迭代循环:for/else


    普通循环:while/else


    其他语句:pass语句、break语句、continue语句、return语句、raise:触发异常、del:删除引用语句、assert:调试检查、class:类定义语句、try/exception/finally:捕捉异常语句、def:函数定义语句、import:模块导入语句、from:模块属性访问


    with/as:环境管理器......


### ****2、表达式****


   表达式,由一个或多个操作数构成,每个表达式都会产生一个结果,即返回值(表达式是可以用来计算的式子,最终都会有一个值体现)。表达式的作用有两点,一个是放在赋值语句的右边,另一个是作为函数的参数。应用在操作数上的操作由操作符表示。作用在一个操作数上的操作符被称为一元操作符。作用在两个操作符上的操作符被称为二元操作符。两个或两个以上的操作符被组合起来的时候被称为复合表达式。


例如:



a=35;  #语句

b=1+a; #整个式子是语句,但是1+a就是表达式


    三元选择表达式:result = x if y else z(如果y为真result=x,如果y为假result=z)  -->  注:红色部分x if y else z就是三元表达式。



a1=7

a2=8

A=a1 if a1>a2 else a2

A

8


### ****3、语句详解****


#### ****3.1、条件语句****



条件语句语法格式:

if  boolean_expression1:

statement1

[elif boolean_expression2:   #注:可选部分

statement2]

else:

statement3


   注:python中以缩进标记代码的边界。


   注:False:0,None,空对象都会返回False,其他都为True


   注:and,or和not在逻辑判断上与其他语言相同,但是注意and和or的返回


#### ****3.2、while语句****



while语句语法格式:

while bool_expression:

statement1

[else:

statement2]


   注:while循环可包含else分支为可选,bool\_expression为False时执行,但是else用的比较少。表达式判断循环是否结束。


#### ****3.3、for语句****



for语句语法格式一:

for iter_var in iterable:

statement1

for语句语法格式二:

for item_index in range(len(seq)):

statement1


#### 扩展:range()内建函数介绍



range()语法:

range(stop) -> list of integers

range(start, stop[, step]) -> list of integers


    range()函数会返回一个范围的list列表,range(start, stop[, step])可以定义一个步长,生产对应的list列表。



xrange()语法:

xrange(stop) -> xrange object

xrange(start, stop[, step]) -> xrange object


    xrange()类似于range(),但是去遍历一个很大的范围时,xrange()更适合,他不会再内存里创建列表的完整拷贝。只在for循环中,在for循环外没有意义。他返回一个xrange()对象(不是列表,也不是一个迭代器)。他的性能远远高于range()。但是python3.x中取消了python2.x中的range,并且将xrange重新定义为range


例如:



li=[‘a’,‘b’,‘c’,‘d’]

for index in range(len(li)):

print(li[index])

a

b

c

d


~~~~>>> type(xrange(10))   #python2.x中才有,python3.x中为range~~~~


~~~~<type 'xrange'>~~~~



range(10) #python3.x中,返回一个range对象

range(0, 10)

list(range(10)) #python3.x中实现python2.x中的range

[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]


#### 3.4、****break、continue、pass语句****


    a)break语句


   break语句可用在while和for循环中,作用是跳出循环


   b)continue语句


    continue语句可用在whiel和for循环中,作用是终止当前循环,进行下一次循环。


   c)pass语句


   pass语句,作用是不做任何事情。


例如:



def func():

pass    注:表示里面不做任何事情。

注:这样简化了操作,有些定义格式下面必须写上语句,直接写pass更方便


### 4、迭代器(iterator)和iter()函数


#### 4.1、迭代器概述


    迭代器,它为序列对象提供一个类序列的接口。Python中的迭代可以迭代序列对象,也可以得带非序列类型,包括用户自定义对象。


    迭代器需要遵循以下协议:对象必须提供一个next()方法,执行该方法时,要么返回迭代中的下一项,要么引起一个StopIteration异常。迭代器只能往前访问,不能向后移动,也不能回到开始。在python中,支持迭代协议就是实现对象的\_\_iter\_\_()和\_\_next\_\_()方法。


    \_\_iter\_\_()方法:返回迭代器对象本身;


    \_\_next\_\_()方法:返回容器中的下一个元素,在结尾时引发StopIteration异常终止迭代器。


    内置函数iter()、next(),本质上都是用的对象的\_\_iter\_\_()、\_\_next\_\_()的方法。


    reversed() 内建函数将返回一个反序访问的迭代器. enumerate() 内建函数同样也返回迭代器.


    另外两个新的内建函数, any() 和 all() , 在 Python 2.5 中新增, 如果迭代器中某个/所有条目的值都为布尔真时,则它们返回值为真。 Python 还提供了一整个 itertools 模块, 它包含各种有用的迭代器。


例如:自定义迭代器



class MyRange(object):

def init(self, n):

self.idx = 0

self.n = n

def iter(self):

return self

def next(self):

if self.idx < self.n:

val = self.idx

self.idx += 1

return val

else:

raise StopIteration()

myrange=MyRange(5)

myrange.next()

0

myrange.next()

1


注:此处没有用for循环迭代,是因为在python3.x中for循环中对迭代的对象进行了校验,使用之后抛出如下错误:iter() returned non-iterator of type 'MyRange'。但是在python2.x中就可以正常迭代。


#### 4.2、可迭代对象(iterable)


   实现了迭代器协议的对象,就是可迭代对象。


   如何实现迭代器协议:对象内部定义了一个\_\_iter\_\_()方法。


   在Python中,list、tuple、dict、set以及生成器对象都是可迭代对象。如果不确定哪个可迭代,可以使用内置函数iter()测试。


   所有的iterable均可以通过内置函数iter()转化为iterator语法如下:


   iter(collection) -> iterator


   iter(callable, sentinel) -> iterator


例如:



iter([1,2,3]) #返回listterator对象
<list_iterator object at 0x0000000002C75340>
iter(666)
Traceback (most recent call last):
File “<pyshell#1>”, line 1, in
iter(666)
TypeError: ‘int’ object is not iterable


#### 4.3、迭代器的优点


   a)对于支持随机访问的数据结构:list、tuple等,迭代器和经典的for循环(索引访问)相比,并无优势,反而失去了索引值。不过可以使用内置函数enumerate()找回这个索引值。但对于无法随机访问的数据结构:set(),迭代器是唯一的访问元素的方式。


   b)省内存:迭代器不需要事先准备好整个迭代过程中的所有元素,仅仅在迭代到某个元素时才计算该元素,而在这之前或之后,元素可以不存在或销毁。这也是迭代器的一大优点:适合用于遍历一个巨大的或无限的集合,比如几个G的文件。


## ****第四章 文件对象及输入输出****


## ****一、文件对象****


### ****1、文件基本概述****


   文件是计算机中由os(操作系统)管理的具有名字的存储区域。通常用户交互、读写文件、访问网页等,我们称之为输入和输出(I/O)。文件对象不仅可以用来访问普通磁盘文件,而且可以访问其他类型抽象层面上的文件。文件分为:文本文件和二进制文件。


    **file对象也是一个可迭代对象。**


#### 1.1、Python的内置函数:open()


  open()用于打开文件和创建文件对象。



语法格式:

open(name [,mode[,bufsize]]) --返回file 对象

name:文件名

Mode:模式-文件打开的模式,不写默认以读方式打开

bufsize:定义输出缓存

0-表示无输出缓存

1-表示使用缓冲

负数-表示使用系统默认设置

正数-表示使用近似指定大小的缓冲

与之等效的方式:file()-文件对象内建方法

file(name[, mode[, buffering]]) -> file object


例如:



f1=open(r’C:\mypython\test.txt’,‘r’)

s=f1.read()

print(s)

你好,python


### 2、文件访问模式




|  |  |
| --- | --- |
| 文件模式 | 操作 |
| 说明:[r:只读,w:写入,a:附加]       + 表示同时支持输入、输出操作(可读、可写)       附加b 表示以二进制方式打开       U表示换行符:不同平台换行符可能不同。\n \r 注:b对于unix/linux系统来说,可有可无,因为它们把所有的文件都当做二进制文件。b不能作为第一个字符出现 |
| r | 以读方式打开(此方式打开的文件必须已存在) |
| rU/Ua | 以读方式打开,同时提供通用换行符支持 |
| w | 以写方式打开(文件若存在先清空,然后重新创建) |
| a | 以追加模式打开(从EOF(end of file)开始,必要时创建新文件) |
| r+ | 以读写模式打开。文件内容不清空,但会从头开始替换新内容 |
| w+ | 以读写模式打开。一旦调用文件内容清空,可重新写入 |
| a+ | 以读写模式打开。在文件尾部追加。 |
| rb | 以二进制读模式打开 |
| wb | 以二进制写模式打开 |
| ab | 以二进制追加模式打开 |
| rb+ | 以二进制度读写模式打开 |
| wb+ | 以二进制度读写模式打开 |
| ab+ | 以二进制度读写模式打开 |


### 3、文件对象的内置方法




|  |  |
| --- | --- |
| 文件对象方法 | 描述 |
| file.close() | 关闭文件,关闭后不能进行读写。不显示关闭文件,那么可能丢失输出缓冲区中的数据。 |
| file.fileno() | 返回文件的描述符 |
| file.flush() | 刷新文件的内部缓冲区,直接把内部缓冲区的数据立刻写入文件,而不是被动的等待输出缓冲区写入。默认返回None。 |
| file.isatty() | 判断file是否是一个tty设备(是否连接到一个终端设备) |
| file.next() | 返回文件的下一行,如没下一行是报错 |
| file.read([size]) | 从文件读取size个字节,当为给定size或给定负值的时候,读取剩余的所有字节,作为字符串返回,没给定size默认为-1 |
| file.readinto(buf,size) | 从文件读取size个字节到buf缓冲器(已废弃) |
| file.readline([size]) | 从文件中读取并返回一行(包括结束符),或者返回最大size个字符 |
| file.readlines([size]) | 从文件读取所有行并作为一个列表返回(包含所有行的结束符),如果给定size且大于0,那么将返回总和大约为size字节行。 |
| file.xradlines() | 用于迭代,可以替换readlines()的一个更高效的方法 |
| file.seek(offset[, whence]) | 从文件中移动文件指针,从where(0代表文件起始,1代表当前位置,2代表文件末尾)偏移offset字节,默认返回None |
| file.tell() | 返回当前在文件中的位置,返回integer |
| file.truncate([size]) | 截取文件到最大size字节,默认为当前文件位置,默认返回None |
| file.write(str) | 向文件写入字符串,默认返回None |
| file.writelines(seq) | 项文件写入字符串序列seq,默认返回None |
|   |
| 文件对象属性 | 描述 |
| file.closed | True表示文件已经被关闭,否则为False |
| file.encoding | 文件所使用的编码-当unicode字符串被写入数据时,他们将自动使用file.encoding转换为字节字符串。若file.encoding为None时使用系统默认编码 |
| file.mode | 文件打开时使用的访问模式 |
| file.name | 文件名 |
| file.newlines | 未读取到行分隔符时为None,只有一种行分隔符是为一个字符串,当文件有多种类型的行结束符是,则为一个包含所有当前所遇到的行结束符的列表 |
| file.softspace | 为0表示在输出一数据后,要加上一个空格符,1表示不加。这个属性一般用不着,有程序内部使用 |


例如:



f1=open(r’C:\mypython\test.txt’)

content=f1.read()

print(content)

你好,python

你好,我是第二行

f1=open(r’C:\mypython\test.txt’,‘a+’)

f1.write(‘你好,我是写入\n’)

f1.close()   #注:关闭时,会强制写入文件,不加这句则还未真正写入

f1=open(r’C:\mypython\test.txt’)

f1=open(r’C:\mypython\test.txt’,‘a+’)

f1.write(‘你好,我是写入\n’)

f1.flush()  #注:此刻缓冲区中的数据被写入文件

f1.close()

f1=open(r’C:\mypython\test.txt’)

for line in f1:

print(line)

你好,python

你好,我是第二行你好,我是写入

你好,我是写入

f1=open(r’C:\mypython\test.txt’)

data=[line.strip() for line in f1.readlines()]

f1.close()

for line in data:

print(line)

你好,python

你好,我是第二行你好,我是写入

你好,我是写入


## 二、****文件系统****


### 1、基本概述


   对文件系统的访问,大多数通过python的os模块实现。Os模块是python访问操作系统的主要接口。除了对进程和进程运行环境进行管理外,os还负责了大部分的文件系统操作。os.path模块可以完成一些针对路劲名的操作。


   操作系统相关模块的名字:


   Windows      (os.name-->)        nt


   Linux/Unix   (os.name-->)        posix


   DOS          (os.name-->)        dos


   OS/2         (os.name-->)        os2(微软最终放弃OS/2转向windows)


### 2、os模块的内建属性/方法




|  |  |
| --- | --- |
| 属性/方法 | 描述 |
| 属性 |
| os.name | 执行平台的类型 |
| os.linesep | 当前平台使用的行终止符号,windows下为‘\r\n’,linux下为‘\n’ |
| os.sep | 输出操作系统特定的路劲分隔符 |
| os.pathsep | 分隔文件路劲的字符串,windos下; |
| os.curdir | 返回当前目录(‘.’) |
| os.pardir | 获取当前目录的父目录(‘..’) |
| os.environ | 获取系统的环境变量 |
| 方法 |
| 文件处理 |
| remove(path)/unlink(path) | 删除一个文件 |
| rename(old, new)/ renames(old, new) | 重命名文件 |
| stat()/lstat() | 获取文件/目录信息[st\_mode(权限模式)、st\_ino、st\_dev、st\_nlink、st\_size(文件字节大小)、st\_atime(最近一次访问时间)、st\_mtime(最近修改时间)、st\_ctime(平台相关,unix下最近一次元数据修改时间,window下创建时间] |
| utim(path, (atime, mtime)) | 更新时间戳 |
| tmpfile() | 创建一个新的临时文件(没有目录) |
| walk(top,topdown=True, οnerrοr=None, followlinks=False) | 生成一个目录树下的所有文件名:top表示需要遍历的目录树路径。Topdown的默认值为True,表示先返回目录树下的文件,然后在遍历目录树的子目录,为False时,表示先遍历目录树的子目录,返回目录下的文件,最后再返回根目录下的文件。Onerror的默认值是None,表示忽略文件遍历时产生的错误,如果不为空,则提供一个自定义函数提示错误信息后继续遍历或抛出异常中止遍历。 |
| 目录/文件夹 |
| chdir(path) | 改变当前脚本的工作目录,相当于shell下cd |
| listdir(path) | 列出指定目录下的所有文件和字目录,包括隐藏文件-返回字符串list |
| getcwd()/getcwdu() | 获取当前工作目录,即当前python脚本工作的目录路径--返回字符串str/后面的返回unicode形式字符串。 |
| mkdir(path[, mode=0777]) | 创建目录(单级) |
| makedirs(name, mode=511) | 创建多层目录(递归) |
| rmdir(path) | 删除单级目录,若目录不为空无法删除,报错 |
| removedirs(path) | 若目录为空,则删除,并递归到上一级,若也为空,则删除... |
| 访问/权限 |
| access(path, mode) | 检验权限模式,返回bool类型 |
| chmod(path, mode) | 改变权限模式 |
| umask(new\_mask) | 设置默认权限模式 |
| 文件描述操作符 |   |
| open(filename,flag[,mode=0777]) | 底层的操作系统open--返回fd,即文件描述符(对于文件使用内置函数open) |
| read(fd,buffersize)/write() | 根据文件描述符读取/写入 |
| dup(fd) | 赋值文件描述符-返回fd2 |
| dup2(old\_fd, new\_fd) | 赋值到另一个文件描述符设备号 |
| 其他方法 |
| system(command) | 运行shell命令--返回exit\_status |


例如:



fd=os.open(r’E:\mypython\test.txt’,os.O_RDWR)

r=os.read(fd,12)

print®

‘\xc4\xe3\xba\xc3\xa3\xacpython’

print(r.decode(‘gbk’))

你好,python


### 3、os.path模块内建方法




|  |  |
| --- | --- |
| 方法 | 描述 |
| basename(p) | 去掉目录路径,返回文件名 |
| dirname(p) | 去掉文件名,返回目录路径 |
| join(path, \*paths) | 将分离的各部分组合成一个路径名 |
| split(p) | 返回(dirname(),basename())元组 |
| splitdrive(p) | 返回(drivename,pathname)元组 |
| splitext(p) | 返回(filename,extension)元组 |
| getatime(filename) | 返回最近访问时间 |
| getctime(filename) | 返回文件创建时间 |
| getmtime(filename) | 返回最近文件修改时间 |
| getsize(filename) | 返回文件大小(以字节为单位) |
| exists(path) | 指定路径(文件或目录)是否存在 |
| isabs(s) | 指定路径是否为绝对路径 |
| isdir(...) | 指定路径是否存在且为一个目录 |
| isfile(path) | 指定路径是否存在且为一个文件 |
| islink(path) | 指定路径是否存在且为一个符号链接 |
| ismount(path) | 指定路径是否存在且为一个挂载点 |


例如:



import os

import os.path

os.name

‘nt’

os.getcwd()    #获取当前工作目录

‘C:\cx\python’

os.chdir(‘C:\mypython’) #切换工作目录

os.getcwd()

‘C:\mypython’

os.mkdir(‘test’)        #创建一个目录

os.chdir(r’C:\mypython\test’)

os.getcwd()

‘C:\mypython\test’

os.listdir(‘.’)        #当前目录下,没有文件夹/文件

[]

cwd=os.getcwd()

cwd

‘C:\mypython\test’

f=open(‘test’,‘w’)    #写入文件

f.write(‘line1\n’)

f.write(‘line2\n’)

f.close()

os.listdir(‘.’)       #当前目录下有一个文件

[‘test’]

os.rename(‘test’,‘test.txt’)  #重命名文件

os.listdir(‘.’)

[‘test.txt’]

path=os.path.join(cwd,os.listdir(cwd)[0]) #拼接完整的文件路径

path

‘C:\mypython\test\test.txt’

os.path.isfile(path)    #判断是否是文件

True

os.path.split(path)

(‘C:\mypython\test’, ‘test.txt’)

os.remove(path)        #删除文件

os.listdir(cwd)        #文件列表为空,文件被删除

[]

os.pardir              #当前目录的父级目录

‘…’

os.chdir(os.pardir)

os.getcwd()

‘C:\mypython’

os.rmdir(‘test’)       #删除空目录


## 第五章 错误和异常


## 一、基本概述


#### 1、错误


   a)语法错误。代码不符合解释器或者编译器语法,执行前可以修改。


   b)逻辑错误。不完整或不合法输入(传递参数不合法)或者计算出现问题(比如出现除0操作)。


#### 2、异常


   即使是在语法上完全正确的语句,尝试执行它的时候,也可能会发生的错误。即在程序运行中检测出的错误,称之为异常。它通常不会导致致命的问题。异常类型作为错误信息的一部分。


   出现异常的原因:


   a)程序逻辑或算法问题


   b)运行过程中计算机错误(内存不够等)


  异常的两个步骤:


   异常产生,检查到错误且解释器认为是异常,抛出异常。


   异常处理,截获异常,忽略或者终止程序处理异常,减轻错误带来的影响等。


  Python的运行时错误称作异常。


    语法错误:软件的结构上有错误而导致的不能被解释器解释或不能被编译器编译


    逻辑错误:由于不完整或不合法的输入所致,也可能是逻辑无法生成、计算或者输出结果需要的过程无法执行等。


    Python异常是一个对象,表示错误或意外情况。在python检测到一个错误时,将触发一个异常。可以通过传导机制传递一个异常对象,也可以在代码中手动触发异常。


    Python异常可以理解为:程序出现了错误而在正常控制流以外采取的行为。可分为两个阶段:


    第一阶段:解释器触发异常,此时当前程序流将被打断


    第二阶段:异常处理,如忽略非致命性错误。减轻错误带来的影响等。


 Python错误处理:


    python的默认处理:停止程序,打印错误消息,也可以使用try语句处理异常并从异常中恢复。


#### 3、常见异常




|  |  |
| --- | --- |
| ****异常名称**** | ****描述**** |
| Exception | 所有异常的基类 |
| StopIteration | 当一个迭代器的 next()方法不指向任何对象时引发 |
| SystemExit | 由 sys.exit()函数引发 |
| StandardError | 除了StopIteration异常和SystemExit,所有内置异常的基类 |
| ArithmeticError | 数值计算所发生的所有错误的基类 |
| OverflowError | 当数字类型计算超过最高限额引发 |
| FloatingPointError | 当一个浮点运算失败时触发 |
| ZeroDivisonError | 当除运算或模零在所有数值类型运算时引发 |
| AssertionError | 断言语句失败的情况下引发 |
| AttributeError | 属性引用或赋值失败的情况下引发 |
| EOFError | 当从 raw\_input() 与 input() 函数输入,到达文件末尾时触发 |
| ImportError | 当一个 import 语句失败时触发 |
| KeyboardInterrupt | 当用户中断程序执行,通常是通过按 Ctrl+c 引发 |
| LookupError | 所有查找错误基类 |
| IndexError KeyError | 当在一个序列中没有找到一个索引时引发 当指定的键没有在字典中找到引发 |
| NameError | 当在局部或全局命名空间中找不到的标识引发 |
| UnboundLocalError EnvironmentError | 试图访问在函数或方法的局部变量时引发,但没有值分配给它。 Python环境之外发生的所有异常的基类。 |
| IOError IOError | 当一个输入/输出操作失败,如打印语句或 open()函数试图打开不存在的文件时引发 操作系统相关的错误时引发 |
| SyntaxError IndentationError | 当在Python语法错误引发;没有正确指定缩进引发。 |
| SystemError | 当解释器发现一个内部问题,但遇到此错误时,Python解释器不退出引发 |
| SystemExit | 当Python解释器不使用sys.exit()函数引发。如果代码没有被处理,解释器会退出。 |
|   | 当操作或函数在指定数据类型无效时引发 |
| ValueError | 在内置函数对于数据类型,参数的有效类型时引发,但是参数指定了无效值 |
| RuntimeError | 当生成的错误不属于任何类别时引发 |
| NotImplementedError | 当要在继承的类来实现,抽象方法实际上没有实现时引发此异常 |


#### 4、异常的检测与处理


   异常通过try语句来检测,任何在try语句中的代码都会被检测,以检测有误异常发生


   try有两种形式:


   1)try-except:检测和处理异常


       可以有多个exception


       支持else子句处理没有探测异常的执行的代码


   2)try-finally


       仅检查异常并做一些必要的清理工作,仅能有一个finallly


   复合形式:try-except-finally



语法:

try:

try_suite

except exception[,reason]:

except_suite

except: #没有写任何原因,可以捕获一切异常

else:  #try中没有产生任何异常才会进行

else

finally: #不管怎样都会执行


#### 5、raise语句


   raise语句可以显示触发异常。法语:Raise[someException [,args[,traceback]]]


   注:someException :可选,异常名字,仅能使用字符串、类或实例


          args:可选,以元组的形式传递给异常的参数


          traceback:可选,异常触发时新生成的一个用于异常-正常化的跟踪记录


## 第六章 函数


## ****一、函数概述****


### ****1、函数定义****


   函数就是完成特定功能的一个语句组,这组语句可以作为一个单位使用,并且给它取个名字。使用函数的好处就是可以分解流程及减少冗余代码实现代码的重用。



语法:
def functionName([parameters])

“function_documentation_string文档说明字符串”

statements

[return value]

注:def 是一个可执行语句,可以出现在任何能够使用语句的地方,甚至可以嵌套于其他语句中。如:if或while中。def相当于创建了一个对象并且将其值赋给了一个变量名(即函数名)。

注:return用于返回结果对象,其为可选;无return语句的函数自动返回None对象。返回多个值时,彼此间使用逗号分隔,且组合为元组形式返回一个对象。

注:python中函数不允许在函数未声明之前,对其行引用。


### ****2、函数的调用方式****


   和大多数语言相同,python中函数的调用方式使用:()进行调用。但是在python中函数的操作符同样用于类的实例化。


   a)标准化参数(默认按参数顺序)调用:


     functionName(arg1,arg2...)


   b)关键字参数调用(不按顺序匹配):


     functionName(arg2=value2,arg1=value1...)


例如:



def func1(host,port):

    print(dict([(host,port)]))

func1(‘127.0.0.1’,8080)   #注:按顺序调用

{‘127.0.0.1’: 8080}

func1(port=8080,host=‘127.0.0.1’)  #注:不按顺序调用

{‘127.0.0.1’: 8080}


注:尽量不要使用可变对象作为函数的默认值,如果参数不显示的赋值,那么所谓的参数默认值只不过是指向那个在compile阶段就已经存在的对象的指针。


例如:



def func_default_args(my_list=[],element=None):

my_list.append(element)

return my_list

list1=func_default_args(element=1)

list1

[1]

list2=func_default_args(element=2)

list2

[1, 2]


注:python中的任何变量都是对象。Python中的参数只支持引用传递。


    值传递:被调函数的形式参数作为被调函数的局部变量处理,即在堆栈中开辟了内存空间以存放由主调函数放进来的实参的值,从而成为了实参的一个副本。值传递的特点是被调函数对形式参数的任何操作都是作为局部变量进行,不会影响主调函数的实参变量的值。


    引用传递:被调函数的形式参数虽然也作为局部变量在堆栈中开辟了内存空间,但是这时存放的是由主调函数放进来的实参变量的地址。被调函数对形参的任何操作都被处理成间接寻址,即通过堆栈中存放的地址访问主调函数中的实参变量。正因为如此,被调函数对形参做的任何操作都影响了主调函数中的实参变量。


### ****3、函数参数****


#### ****3.1、位置参数****


   位置参数,就是有一定顺序的参数,其个数和位置都要匹配,不可缺少的参数。(注:当然可将关键字参数带入,位置参数可以不按顺序匹配)


#### ****3.2、默认参数****


   默认参数就是如果在函数调用时没有为参数提供值,则使用预定义的默认值。即默认参数是可选的。每个默认参数都会跟着一个默认的赋值语句,且位置参数必须出现在默认参数之前。



语法: def func(posargs,defarg1=value1,defarg2=value2…):

“function_documentation_string”

Statement


例如:



def func(host,port=8080,stype=‘tcp’):

    print(host,port,stype)

func(‘127.0.0.1’,80,‘udp’)  #不使用默认参数

127.0.0.1 80 udp

func(‘127.0.0.1’)           #使用默认参数

127.0.0.1 8080 tcp

func(port=80,host=‘127.0.0.1’)  #唯一不能缺少的就是位置参数

127.0.0.1 80 tcp


#### ****3.3、可变长度的参数****


****1)非关键字可变长参数****


  在函数被调用的时候,所有的形参(必须的和默认的)都将赋值给函数中声明的局部变量。剩下的非关键字参数将按顺序插入到一个元组中便于访问。使用****一个星号****标记。



语法:

def function_name([formal_args,]*vargs_tuple)

“function_document_string”

Statement


例如:



def func(arg1,arg2,*arg3):

print(arg1,arg2,arg3)

func(1,2,3,4,5) #注:如果没有额外的参数,元组为空

1 2 (3, 4, 5)


2)****关键字变量参数****


  参数被放入一个字典中,字典中的键为参数名,值为相应的参数值。为了区分关键字参数和非关键字参数,使用****两个星号****标记。



语法:

def function_name([formal_args,][*vargs_tuple,] **vargsd)

“function_document_string”

Statement


例如:



def func(arg1,arg2=‘def’,**arg3):
print(arg1,arg2,type(arg3))
for item in arg3.keys():
print(item,“–”,arg3[item])

func(‘参数1’,a=‘1’,b=‘2’)
参数1 def <class ‘dict’>
a – 1
b – 2


### ****4、函数种类****


    **全局函数(内置函数****)**:python内嵌的一些函数。


    **自定义函数**:根据自己的需求,来进行定义函数。【自定义函数可分为:普通函数、匿名函数:一行代码实现一个函数功能。(如:**lambda函数**:表达式(匿名函数))、递归函数】


    函数相关的语句和表达式:global 、nonlocal 、yield 、lambda


    Lambda表达式返回可调用的函数对象。Python中使用lambda关键字创建匿名函数。 语法:lambda [arg1[,arg2,...argN]]:expression   即:lambda 参数:表达式


例如:



sum1=lambda x,y=2:x+y

sum1(1)

3


### 5、****generator生成器****


#### 5.1、生成器概述


   生成器的作用是一次产生一个数据项,并把数据项输出。Generator函数可以用在for循环中变量。Generator函数所具有的每次返回一个数据项的功能,使用迭代器的性能更佳。生成器还有一个很重要的特性就是在调用过程中局部变量和执行状态可以自动保存。


   优势:python对延迟提供了更多的支持。生成器会在需要的时候才产生结果,而不是立即产生结果。这样节省了内存空间,并且时间允许计算时间分散到各个请求结果。



Generator函数语法:

def functionName(args…)

yield 表达式


例如:



def reverse(data):

for index in range(len(data)-1,-1,-1):

yield data[index]

for char in reverse(‘golf’):

print(char)

f

l

o

G

gen=reverse(‘golf’) #获得了一个生成器

gen.next() #注意:python3.x中使用__next__()去获取迭代元素

‘f’                #注意:python2.x中使用next()去获取迭代元素


解释:当调用生成器函数的时候,函数返回一个生成器对象,并没有执行。当\_\_next\_\_()方法第一次被调用的时候,生成器才开始执行,执行到yield语句处停止。\_\_next\_\_()方法返回的值就是yield语句处的参数,当继续调用\_\_next\_\_()方法的时候,函数接着上一次停止的yield语句处执行,并到下一个yield处停止。如果后面没有yield就抛出stopIteration异常。


另外还有一种简单的方式,通过表达式生成generator,但是这种缺乏通用性。


>>> g=(x\*x for x in range(10))


>>> type(g)


<class 'generator'>


#### 5.2、迭代器iterator和生成器generator的异同


    Generator可以说是一种特殊的迭代器,内部支持了生成器协议,不需要明确的定义\_\_iter\_\_()和\_\_next\_\_()方法。生成器函数可以通过常规的def语句来定义,但是不用return返回,而是用yield一次返回一个结果。




|  |  |
| --- | --- |
| Generator常用方法 | 描述 |
| \_\_iter\_\_(self, /) | 实现了iter()迭代器 |
| \_\_next\_\_(self, /) | 实现了next() |
| close()  | 关闭生成器,对关闭的生成器后再次调用next或send将抛出StopIteration异常 |
| send(arg)  | send(value)方法传入的值作为yield表达式的值 |
| throw(typ[,val[,tb]])  | 抛出异常 |


例如:



def csrange(n):

i = 0

while i<n:

val = yield i

print(‘val is :’,val)

i+=1

cs=csrange(5)

cs.next()

0

cs.send(99) #将send(value)将value作为yield表达式的值

val is : 99

1

cs.send(None) #注:等价于调用next()/next()

val is : None

2

next(cs)   #注:内建函数next()等价于__next__()

val is : None

3


注:调用send()方法时,生成器必须处于yield暂停状态,否则将报错。


### ****6、部分内建函数****




|  |  |
| --- | --- |
| 内建函数 | 描述 |
| apply(func[,args[,kwargs]]) | 用可选的参数来调用func,args为非关键字参数,kwargs关键字参数,返回值是函数调用的返回值。相当于把函数参数存放在一个元组或字典中,间接调用函数。 |
| filter(function or None, sequence) | 调用一个布尔函数来迭代seq中的每个元素,返回一个使函数值为True的元素序列。如果为None,表现为一个身份函数,返回序列中不为假的所有元素。 |
| map(function, sequence[, sequence, ...]) | 将函数作用于给定序列的每个元素,并用一个列表来提供返回值。如果为None,函数表现为一个身份函数,返回一个含有每个序列中元素几个的n个元组列表 |
|  reduce(function, sequence[, initial]) | 将二元函数作用于序列的元素,每次携带一对,连续的将现有的结果和下一个值作为函数参数 |


例如:



def say(a,b):

print(a,b)

apply(say,(‘hello’,‘python’))

hello python

def odd(n):

return n%2

print filter(odd,range(9))    #过滤掉不符合条件的元素

[1, 3, 5, 7]      #[item for item in iterable if function(item)]i

print filter(None,range(9))   #过滤掉为False的元素

[1, 2, 3, 4, 5, 6, 7, 8]  #[item for item in iterable if item]

map(lambda x:x*2,[1,2,3,4])   #对序列中的每项都执行函数并返回

[2, 4, 6, 8]

map(None,[1,2,3,4,5,6])

[1, 2, 3, 4, 5, 6]

map(None,[1,2],[3,4])

[(1, 3), (2, 4)]

reduce(lambda x,y:x+y,range(5))#相当于:((((0+1)+2)+3)+4)

10


## 第七章 模块


## 一、模块概述


#### 1、模块定义


     模块是最高级别的程序组织单元,他将程序代码和数据封装起来以便重用。每一个.py文件都是一个模块,每个模块都有自己的名称空间,python允许导入其他模块以实现代码的重用。Python中,模块也是对象,一个模块被导入时,模块顶层的所有变量名都会变成模块的属性。


    模块首次导入(或重载)时,python会立即执行模块文件的顶层程序代码(不在函数内的代码),而位于函数主体内的代码直到函数被调用时才会执行。例如:def function:...函数的定义也是顶层程序代码,定义也会执行,只是内部的代码,需要调用时才会执行。


    Python自带的模块,又叫标准库模块。使用 help('modules')可以获取当前可导入的模块。


    Python中自带了很多实用的模块,称为标准链接库。python3.8中有350多个模块,包括:操作系统接口、对象永久保存、文字模式匹配、网络和Internet脚本、GUI构建......


#### 2、导入模块


    在导入模块时只能使用模块名,不能使用带.py后缀的模块文件名。


**2.1、import语句**


     导入指定的整个模块,包括生成一个以模块命名的名称空间,语法如下:


     import module1[,module2,[...moduleN]]


     import module as module\_new


注:重新定义一个名称空间,module被替换,如果其它的模块名称重复,而不重新命名的话会覆盖其它的名称空间。


    from-import语句:


    常用于只导入指定模块的部分(或所有)属性至当前名称空间。语法如下:


    form module import name1[,name2[,...nameN]]


    说明:import和form都是隐式的赋值语句,import是将整个模块对象赋值给一个变量名(名称空间),from将一个或多个变量名赋值给导入此模块的模块中的同名对象。


例如:新建module1.py,以UTF-8编码格式保存


def printer(str1):


    print(str1)


案例:将整个模块对象赋值给一个变量名   



import module1
module1.printer(‘hello python’)
hello python


注:也可以这么写:sys=\_\_import\_\_('sys'),还可以使用as重命名import语句扩展(as-重命名)



import module1 as md1

md1.printer(‘hello python’)

hello python


**2.2、from 语句**


  将一个或多个变量名赋值给另一个模块中的同名对象。也就是把这个变量名导入到当前的作用域。



from module1 import printer

printer(‘hello python’)

hello python

from module1 import * #把模块中所有的变量名复制到当前作用域内

printer(‘hello python’)

hello python


    Python中的导入其实是运行时的运算。程序第一次导入指定文件时,会执行三个步骤:


    a)找到模块文件


        在指定的路径下搜索模块文件   


    b)编译成字节码(需要时)


        文件导入时就会编译,顶层的.pyc字节码文件在内部使用后会被丢弃,只有被导入的文件才会留下.pyc文件


    c)执行模块的代码来创建其所定义的对象


       模块文件中的所有语句都会依次执行,从头至尾,而此步骤中任何对变量的赋值运算,都会产生所得到的模块文件的属性。


****注意1:****import模块的搜索路径:主目录、pythonPath目录(如果设置了环境变量)、标准库目录、.pth文件中配置的目录(如果存在)。而这组成了sys.path,也就是模块的搜索路径。


例如:



import sys

sys.path

[‘’, ‘C:\Users\Administrator\AppData\Local\Programs\Python\Python38\Lib\idlelib’, ‘C:\Users\Administrator\AppData…’]


注:除了改变上面的路径外,sys.path返回的是一个列表,我们可以在列表中添加自定义搜索路径。


我在C:\mypython目录中新建一个moduleA.py文件,代码如下:



#––coding:utf-8–

name=‘我是一个自定义目录里的模块’

def printer()

print(name)

import moduleA

Traceback (most recent call last):

File “<pyshell#0>”, line 1, in

import moduleA

ModuleNotFoundError: No module named ‘moduleA’

sys.path.append(‘C:\mypython’)

sys.path

[‘’, ‘C:\Users\Administrator\AppData\Local\Programs\Python\Python38\Lib\idlelib’, ‘C:\Users\Administrator\AppData\Local\Programs\Python\Python38\python38.zip’, ‘C:\Users\Administrator\AppData\Local\Programs\Python\Python38\DLLs’, ‘C:\Users\Administrator\AppData\Local\Programs\Python\Python38\lib’, ‘C:\Users\Administrator\AppData\Local\Programs\Python\Python38’, ‘C:\Users\Administrator\AppData\Local\Programs\Python\Python38\lib\site-packages’, ‘C:\mypython’]

import moduleA

moduleA.printer()

我是一个自定义目录里的模块


****注意2:****模块在第一次导入后,再次导入会跳过上面三个步骤,只提取内存中已加载的模块对象。如果想要再次导入的话使用reload函数。Reload函数载入并运行了文件最新版本的代码。


****注意3:****在python2.x中它是内置函数,直接调用就可以了,但是在python3.x中不是内置函数。python3.0把reload内置函数移到了imp标准库模块中。它仍然像以前一样重载文件,但是,必须导入它才能使用。


#### 3、命名空间


    **命名空间是用来储存变量名和对象绑定关系的,在 Python 中用字典来储存。命名空间存在的意义就是更好的管理名称,使得代码块之间的命名可以相同,却又不冲突,**命名空间是运行时的运行环境决定的**。**模块的命名空间可以通过属性\_\_dict\_\_或者dir(module)来获取(**其实模块的名称就是一个名称空间**)。命名空间一般可分为三种(局部命名空间->全局命名空间->内建命名空间):


**局部命名空间(local names)**,函数中定义的名称,记录了函数的变量,包括函数的参数和局部定义的变量。(类中定义的也是),使用locals()获取。


**全局命名空间(global names)**,模块中定义的名称,记录了模块的变量,包括函数、类、其它导入的模块、模块级的变量和常量,使用globals()获取。


**内建命名空间(built-in names**), Python 语言内置的名称,比如函数名 abs、char 和异常名称 BaseException、Exception 等等,可以使用dir(\_\_builtins\_\_)查看。


    为了更好的管理变量,于是作用域就诞生了,****作用域是可以直接访问到名称空间的文本区域****。作用域必定是对某个对象内部而言的,一个函数内部、一个模块全局等。作用域是定义程序该如何搜索确切地“名字-对象”的名称空间的层级关系。作用域又可理解成权限,一块代码对哪些命名空间有权限。模块是一个独立的作用域。作用域有四种(本地作用域->闭合最重要->全局作用域->内建作用域)


    **本地作用域(Local)**:最内层的函数(def或lambda)。


    **闭合作用域(Enclosing)**:嵌套的父级函数的局部作用域,函数的上级函数的局部作用域。如果A函数内定义了一个B函数,那么相对B函数内的变量A函数内的变量处于闭合作用域。


    **全局作用域(Global)**:最外部定义的变量。


    **内建作用域(Built-in)**:内建模块内定义的函数与关键字。


    搜索变量的优先级顺序依次是:局部作用域>外层作用域>当前模块中的全局>python内置的作用域。(LEGB)


    Pyhton能够改变变量作用域的代码段是:模块(module),类(class)、函数(def/lambda)。其他代码块不会引入新的作用域。如:if/elif/else、try/except/finally、for/while并不能涉及变量作用域的更改。


     代码中变量名被赋值的位置,决定了该变量能被访问的范围,函数定义了局部(本地)作用域(局部变量),每次对函数的调用都创建了一个新的局部(本地)作用域。函数返回时,这个局部作用域就被销毁。


     而模块则定义了全局作用域(全局变量)。也就是说创建于模块文件顶层的变量具有全局作用域,对于外部访问就成了一个模块对象的属性。全局作用域的范围仅限于单个文件。当作用域被销毁时,所有保存在该作用域内的变量的值就被丢弃。


命名空间例如:



a = 1 # a 处在全局命名空间,赋值修改的是名称空间,而不是对象。这个赋值语句就是把a放入到了对应的命名空间,然后让它指向一个值为1的整数对象。
print(globals()) # 打印全局命名空间中的内容

def func():
a = 2 # b 处在局部命名空间,#名称是a 对象是2
print(locals()) # 打印局部命名空间内容

func()

print(name) # name 处在内建命名空间

内建命名空间:type、sum、abs

print(dir(builtins))


输出结果:


{'\_\_name\_\_': '\_\_main\_\_', '\_\_doc\_\_': None, '\_\_package\_\_': None, '\_\_loader\_\_': <\_frozen\_importlib\_external.SourceFileLoader object at 0x0000000001D31910>, '\_\_spec\_\_': None, '\_\_annotations\_\_': {}, '\_\_builtins\_\_': <module 'builtins' (built-in)>, '\_\_file\_\_': 'D:/pyDemo/test/moduleA.py', '\_\_cached\_\_': None, 'a': 1}  
 {'a': 2}  
 \_\_main\_\_  
 ['ArithmeticError', 'AssertionError', 'AttributeError', 'BaseException',......, 'str', 'sum', 'super', 'tuple', 'type', 'vars', 'zip']


分析:虽然在同一个模块中,但由于命名空间的不同,在全局模块中存在a,同样在局部命名空间中也可以存在a,他们互不受影响。


    func(),中如果想改变全局作用域中的变量a的值呢?关于作用域会涉及到两个关键字****global关键字和nonlocal关键字。****


    如果想对内层的变量域中的代码想修改global中的变量值,使用global关键字。如果内层的变量域中的代码想修改enclosing中的变量值,使用nonlocal关键字。如果没有使用这两个关键字,对其进行修改,会生成局部变量进行赋值,并且在本作用域使用的时候会覆盖高层作用域的值,但是不影响高层作用域中的值。


例如:



a=100

def func01():

print(a)

a=200

func01()

UnboundLocalError: local variable ‘a’ referenced before assignment

a

100


解释:在预编译的时候,由于在func01()函数中对a进行了赋值,所以在函数这个作用域中的a被视为局部变量。局部变量的优先级高于全局变量。当打印a的时候,这个局部变量还没有被赋值。所以报错了。但是他的赋值并不影响外部全局变量的值。


例如:



is_this_global=‘xyz’

def func02():

global is_this_global

this_is_local = ‘abc’

is_this_global = ‘def’

print(is_this_global+this_is_local)

func02()

defabc

is_this_global  #使用了global关键字,调用函数全局变量值被改变

‘def’


例如:



def func01():

is_this_enclosing=‘xyz’

def func02():

nonlocal is_this_enclosing #使用nonlocal关键字

this_is_local=‘abc’

is_this_enclosing=‘def’

print(this_is_local+is_this_enclosing)

func02()

print(is_this_enclosing)

func01()

abcdef

def


#### 4、包-Packages


    随着我们的应用程序规模越来越大,带有许多模块,我们将相似的模块放在一个包中,而将不同的模块放在不同的包中。这使项目(程序)易于管理且概念清晰。


    包是由一系列模块组成的集合。当不同作的模块进行按文件夹分类后再组成一个整体的库,可以称为包。包是用来组织模块的一个目录。 为了让Python将目录当做内容包,包导入语句的路径内的每个目录中必须包含\_\_init\_\_.py文件,用于标识当前文件夹是一个包。但通常\_\_init\_\_.py为空,仅用于扮演包初始化的挂钩、替目录产生命名空间以及使用目录导入时实现from \* 行为的角色。但也可以设置\_\_all\_\_变量。如果没有\_\_init\_\_.py,则无法识别这是一个包。


    例如:对于Game包,下面有分为Sound、Image、Level包。


![](https://img-blog.csdnimg.cn/20210522234357537.jpg?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3hpYW94aWFuZXIzMjE=,size_16,color_FFFFFF,t_70)


导包语法:


a)可以从包中导入单独的模块:


   import PackageA.SubPackageA.ModuleA,使用时必须用全路径名


b)可以直接使用模块名而不用加上包前缀


   from PackageA.SubPackageA import ModuleA


c)直接导入模块中的函数或变量


   from PackageA.SubPackageA.ModuleA import functionA


### 5、常用模块介绍


    **python中内置了很多模块,模块分为三种:1)自定义模块;2)标准库(包含内置模块);3)开源模块;**


    什么是标准库(内置模块),在Python官方的**[文档](https://bbs.csdn.net/topics/618540462)**这里有说到:


    Python’s standard library is very extensive, offering a wide range of facilities as indicated by the long table of contents listed below. The library contains built-in modules (written in C) that provide access to system functionality such as file I/O that would otherwise be inaccessible to Python programmers, as well as modules written in Python that provide standardized solutions for many problems that occur in everyday programming。


    翻译:Python的标准库非常广泛,提供了各种各样的工具,如下面列出的长目录所示。该库包含内置模块(用C编写,但是也不全是用C),这些模块提供对系统功能的访问,如Python程序员无法访问的文件I/O,以及用Python编写的模块,这些模块为日常编程中出现的许多问题提供标准化的解决方案。


    所以在lib目录下,我们可以看到os.py,却看不到sys.py,原因就是它是操作系统相关,用C语言编写的。内置模块不是标准库,但是内置模块可以划分到标准库一类中去。大多数情况下,对它们之间没有做区分的必要。但是在理解Python的模块查找顺序时,这却是一个至关重要的差异。import寻找模块有两个步骤:


    1)搜索「内置模块」(built-in module)


    2)搜索 `sys.path` 中的路径


    而 `sys.path` 在初始化时,又会按照顺序添加以下路径:


1)当前执行脚本文件所在目录;


    2)环境变量 `PYTHONPATH`中列出的目录(类似环境变量 `PATH`,由用户定义,默认为空);


    3)模块默认安装目录(通常是标准库)。


    **查看python支持的标准库/模块:**



#查看python支持的库/模块

help(‘modules’)

#查看python的内置模块

import sys
print(sys.builtin_module_names) #内置模块
(‘_abc’, ‘_ast’, ‘_bisect’, ‘_blake2’, ‘_codecs’, ‘_codecs_cn’, ‘_codecs_hk’, ‘_codecs_iso2022’, ‘_codecs_jp’, ‘_codecs_kr’, ‘_codecs_tw’, ‘_collections’, ‘_contextvars’, ‘_csv’, ‘_datetime’, ‘_functools’, ‘_heapq’, ‘_imp’, ‘_io’, ‘_json’, ‘_locale’, ‘_lsprof’, ‘_md5’, ‘_multibytecodec’, ‘_opcode’, ‘_operator’, ‘_pickle’, ‘_random’, ‘_sha1’, ‘_sha256’, ‘_sha3’, ‘_sha512’, ‘_signal’, ‘_sre’, ‘_stat’, ‘_statistics’, ‘_string’, ‘_struct’, ‘_symtable’, ‘_thread’, ‘_tracemalloc’, ‘_warnings’, ‘_weakref’, ‘_winapi’, ‘_xxsubinterpreters’, ‘array’, ‘atexit’, ‘audioop’, ‘binascii’, ‘builtins’, ‘cmath’, ‘errno’, ‘faulthandler’, ‘gc’, ‘itertools’, ‘marshal’, ‘math’, ‘mmap’, ‘msvcrt’, ‘nt’, ‘parser’, ‘sys’, ‘time’, ‘winreg’, ‘xxsubtype’, ‘zlib’)


     使用python标准库/模块:



import module
from module.xx.xx import xx
from module.xx.xx import xx as rename
from module.xx.xx import *

pip3 install 开源三方模块


*前面呢,我们也接触到了sys内置模块和os标准库,python中提供了很多这种的标准库/内置模块,常见的有:*


#### 5.1、time(内置模块) & datetime(标准库)



import time

time.localtime([secs]):将一个时间戳转换为当前时区的struct_time。secs参数未提供,则以当前时间为准。
time.time():返回当前时间的时间戳。
time.gmtime([secs]):和localtime()方法类似,gmtime()方法是将一个时间戳转换为UTC时区(0时区)的struct_time。
time.mktime(t):将一个struct_time(UTC+8)转化为时间戳。
time.sleep(secs):线程推迟指定的时间运行。单位为秒。
time.asctime([t]):把一个表示时间的元组或者struct_time表示为这种形式:‘Sun Jun 20 23:21:05 1993’。如果没有参数,将会将time.localtime()作为参数传入。
time.ctime([secs]):把一个时间戳(按秒计算的浮点数)转化为time.asctime()的形式。如果参数未给或者为None的时候,将会默认time.time()为参数。它的作用相当于time.asctime(time.localtime(secs))。
time.strftime(format[, t]):把一个代表时间的元组或者struct_time(如由time.localtime()和time.gmtime()返回)转化为格式化的时间字符串。
time.strptime(string[, format]):把一个格式化时间字符串转化为struct_time。实际上它和strftime()是逆操作。
time.clock():这个需要注意,在不同的系统上含义不同。在UNIX系统上,它返回的是“进程时间”,它是用秒表示的浮点数(时间戳)。

import datetime

datetime.date.today() 本地日期对象,(用str函数可得到它的字面表示(2014-03-24))
datetime.date.isoformat(obj) 当前[年-月-日]字符串表示(2014-03-24)
datetime.date.fromtimestamp() 返回一个日期对象,参数是时间戳,返回 [年-月-日]
datetime.date.weekday(obj) 返回一个日期对象的星期数,周一是0
datetime.date.isoweekday(obj) 返回一个日期对象的星期数,周一是1
datetime.date.isocalendar(obj) 把日期对象返回一个带有年月日的元组
datetime对象:
datetime.datetime.today() 返回一个包含本地时间(含微秒数)的datetime对象 2014-03-24 23:31:50.419000
datetime.datetime.now([tz]) 返回指定时区的datetime对象 2014-03-24 23:31:50.419000
datetime.datetime.utcnow() 返回一个零时区的datetime对象
datetime.fromtimestamp(timestamp[,tz]) 按时间戳返回一个datetime对象,可指定时区,可用于strftime转换为日期表示
datetime.utcfromtimestamp(timestamp) 按时间戳返回一个UTC-datetime对象


#### 5.2、random(标准库)



random.random()#用于生成一个0到1的随机符点数: 0 <= n < 1.0
random.randint(a, b),用于生成一个指定范围内的整数。其中参数a是下限,参数b是上限,生成的随机数n: a <= n <= b
randrange([start], stop[, step]), # 从指定范围内,按指定基数递增的集合中 获取一个随机数。
random.choice(sequence)参数sequence表示一个有序类型。


#### 5.3、os(标准库)



#提供对操作系统进行调用的接口
os.getcwd() 获取当前工作目录,即当前python脚本工作的目录路径
os.chdir (“dirname”) 改变当前脚本工作目录;相当于 shell下cd
os.curdir 返回当前目录: (‘.’)
os.pardir 获取当前目录的父目录字符串名:(‘…’)
os.makedirs (‘dirname1/dirname2’) 可生成多层递归目录
os.removedirs (‘dirname1’) 若目录为空,则删除,并递归到上一级目录,如若也为空,则删除,依此类推
os.mkdir (‘dirname’) 生成单级目录;相当于shell中mkdir dirname
os.rmdir (‘dirname’) 删除单级空目录,若目录不为空则无法删除,报错;相当于shell中rmdir dirname
os.listdir (‘dirname’) 列出指定目录下的所有文件和子目录,包括隐藏文件,并以列表方式打印

前面已经写过


#### 5.4、sys(内置模块)



sys.argv 命令行参数List,第一个元素是程序本身路径
sys.exit (n) 退出程序,正常退出时exit(0)
sys.version 获取 Python 解释程序的版本信息
sys.maxint 最大的 Int 值
sys.path 返回模块的搜索路径,初始化时使用PYTHONPATH 环境变量的值
sys.platform 返回操作系统平台名称


#### 5.5、shutil(标准库)



#高级的 文件、文件夹、压缩包 处理模块

shutil.copyfileobj(fsrc, fdst[, length]) 将文件内容拷贝到另一个文件中,可以部分内容

shutil.copyfile(src, dst) 拷贝文件

shutil.copymode(src, dst) 仅拷贝权限。内容、组、用户均不变

shutil.copystat(src, dst) 拷贝状态的信息,包括:mode bits, atime, mtime, flags

shutil.copy(src, dst) 拷贝文件和权限

shutil.copy2(src, dst) 拷贝文件和状态信息

shutil.rmtree(path[, ignore_errors[, onerror]]) 递归的去删除文件

shutil.move(src, dst) 递归的去移动文件


#### 5.6、json & pickle(标准库)



用于序列化的两个模块

#json,用于字符串 和 python数据类型间进行转换

#序列化

import json
info={
‘name’:‘鲁班’,
‘age’:22
}

f=open(‘test.txt’,‘w’)

f.write(json.dumps(info))#用于将Python数据以字符串的形式写入到文件中

f.close()

#反序列化
f = open(‘test.txt’,‘r’)

data=json.loads(f.read())#从文件中加载出Python的数据类型

print(data[‘age’])

pickle,用于python特有的类型 和 python的数据类型间进行转换

#序列化
import pickle
def sayhi(name):
print(“hello python”,name)

info = {
‘name’:‘鲁班’,
‘age’:22,
‘func’:‘sayhi’
}
f=open(“pickle_test.txt”,‘rb’)

pickle.dump(info,f)#==f.write(pickle.dumps(info))

f.close()

#反序列化
import pickle

f=open(“pickle_test.txt”,‘rb’)

data=pickle.load(f)
print(data[“age”])


#### 5.7、xml、yaml(标准库)



xml是实现不同语言或程序之间进行数据交换的协议,跟json差不多,但json使用起来更简单,不过,以前,在json还没诞生的时候,大家只能选择用xml。

Python也可以很容易的处理ymal文档格式。


#### 5.8、logging(标准库)



import logging
logging.debug(‘debug message’)
logging.info(‘info message’)
logging.warning(‘warning message’)
logging.error(‘error message’)
logging.critical(‘critical message’)


## 第八章 对象和类


    面向过程:根据业务逻辑从上到下写垒代码。


    函数式:将某功能代码封装到函数中,日后便无需重复编写,仅调用函数即可。


    面向对象:对函数进行分类和封装,让开发更快更好更强。


    面向对象编程是一种编程方式,此编程方式的落地需要使用 “类” 和 “对象” 来实现,所以,面向对象编程其实就是对 “类” 和 “对象” 的使用。类就是一个模板,模板里可以包含多个函数,函数里实现一些功能。对象则是根据模板创建的实例,通过实例对象可以执行类中的函数。


## 一、类和对象的创建


### 1、语法及使用



创建类(class是关键字,表示类)

class className:
# 创建类中的函数
def Func(self):
#do something

使用类创建对象

obj = className()


例如:



class Person:
def eat(self):
print(‘eat fruit’)

obj = Person()
obj.eat()
eat fruit


### 2、面向对象三大特性


    如果接触过java,那可能很快就会想到三大特性:封装、继承和多态。在python中也类似。


#### 2.1、**封装**





还有兄弟不知道网络安全面试可以提前刷题吗?费时一周整理的160+网络安全面试题,金九银十,做网络安全面试里的显眼包!


王岚嵚工程师面试题(附答案),只能帮兄弟们到这儿了!如果你能答对70%,找一个安全工作,问题不大。


对于有1-3年工作经验,想要跳槽的朋友来说,也是很好的温习资料!


【完整版领取方式在文末!!】


***93道网络安全面试题***


![](https://img-blog.csdnimg.cn/img_convert/6679c89ccd849f9504c48bb02882ef8d.png)








![](https://img-blog.csdnimg.cn/img_convert/07ce1a919614bde78921fb2f8ddf0c2f.png)





![](https://img-blog.csdnimg.cn/img_convert/44238619c3ba2d672b5b8dc4a529b01d.png)





内容实在太多,不一一截图了


### 黑客学习资源推荐


最后给大家分享一份全套的网络安全学习资料,给那些想学习 网络安全的小伙伴们一点帮助!


对于从来没有接触过网络安全的同学,我们帮你准备了详细的学习成长路线图。可以说是最科学最系统的学习路线,大家跟着这个大的方向学习准没问题。

#### 1️⃣零基础入门


##### ① 学习路线


对于从来没有接触过网络安全的同学,我们帮你准备了详细的**学习成长路线图**。可以说是**最科学最系统的学习路线**,大家跟着这个大的方向学习准没问题。


![image](https://img-blog.csdnimg.cn/img_convert/acb3c4714e29498573a58a3c79c775da.gif#pic_center)


##### ② 路线对应学习视频


同时每个成长路线对应的板块都有配套的视频提供:


![image-20231025112050764](https://img-blog.csdnimg.cn/874ad4fd3dbe4f6bb3bff17885655014.png#pic_center)

**网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。**

**[需要这份系统化资料的朋友,可以点击这里获取](https://bbs.csdn.net/topics/618540462)**

**一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**

  • 26
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值