1.1模塊
什么是模塊:
在計算機程序的開發過程中,隨着程序代碼越寫越多,在一個文件里代碼就會越來越長,越來越不容易維護。
為了編寫可維護的代碼,我們把很多函數分組,分別放到不同的文件里,這樣,每個文件包含的代碼就相對較少,在python中。一個.py文件就稱為一個模塊(Module)
使用模塊的好處:
提高了代碼的可維護性。
其次,編寫代碼不必從零開始。當一個模塊編寫完畢,就可以被其他地方引用。我們編寫程序的時候也經常引用其他模塊,包括python的內置的模塊和第三方模塊。
包(package)的概念:
如果不同的人編寫的模塊名相同怎么辦?
為了避免模塊名沖突,python有引入了按目錄組織模塊的方法,稱為包(Package)
一個abc.py的文件就是一個名字叫abc的模塊。
假設,我們的abc和qaz這兩個模塊名字與其他模塊沖突了,於是我們可以通過包來組織模塊,避免沖突,方法是選擇一個頂層的包名比如MyUser。
引入包以后,只要頂層的包名不與別人 沖突,那所有的模塊都不會與別人沖突。現在abc.py模塊的名字就變成了MyUser.abc,qaz模塊名字就變成了MyUser.qaz.
多級包結構:包.包.模塊
注:每個包目錄下面都會有一個——init——.py文件,這個文件是必須存在的,否則,python就把這個目錄當成普通目錄,而不是一個包。——init——.py可以是空文件,里面可以有程序代碼,因為——init——.py就是一個模塊,模塊名就是MyUser
注:我們自已編寫模塊名時,盡量不要與內置函數或則模塊名字沖突。如同與系統的模塊同名,否則無法導入系統自帶的模塊
模塊分為3種:
1.自定義模塊
2.內置標准模塊(又稱標准庫)
3.第三方模塊(開源模塊)
1.1.1導入模塊
1 #1語法import 2 import module1,module2,module3,module4 3 4 #2from xx import xx 語句 5 from module import name1,name2 6 7 #這個聲明不會把module模塊導入到當前的命名空間,只會把name1,name2單個引入到執行的程序 8 9 from module.xx import name as rename 10 #把來自於modname.xx的name的重新改了一個名字,去掉用這個模塊的方法 11 12 13 from module import * 14 #這提供了一個簡單的方法來導入一個模塊中的所有項目。這個導入的模塊的方法一般不推薦使用,如果引入的其它來源的命名,很有可能覆蓋已有的定義。
模塊的運行本質
#1 import test #2 from modname from test
無論是1,還是2,首先通過sys.pyth找到test.py,然后執行test代碼(全部執行)
區別是1會將test這個模塊名加載到名字空間,而2只會將test這個變量名加載進來。
為模塊添加路徑
#模塊運行時通過sys.path的路徑一步一步查找模塊的 #導入模塊時是根據那個路徑作為基准來進行的呢?即:sys.path #如果sys.path路勁列表中沒有你想要的路徑,可以通過sys.path.append("路徑")來添加 #當前這是臨時添加,如需永久添加則需修改系統的環境變量 import os,sys BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) sys.path.append(BASE_DIR)
開源模塊安裝的常用方法
1 1.yum 2 2.pip 3 3.apt-get
1.1.2__name__
python解釋器把一個特殊變量__name__的值為__main__
#很多模塊文件內容里面都有 if __name__=='__main__': 運行測試代碼程序的邏輯 如果我們寫的模塊文件,需要被別人調用則不會運行下面的程序的邏輯 我們自已使用用,可以些運行整體程序代碼的邏輯 自已用的時候 __name__=='__main__' , __name__的變量就等於'__main__',被當作模塊導入到其他的文件里時, __name__的變量不等於'__main__'
1.2sys模塊

1 sys.argv #在命令行參數是一個空列表,在其他中第一個列表元素中程序本身的路徑 2 sys.exit(n) #退出程序,正常退出時exit(0) 3 sys.version #獲取python解釋程序的版本信息 4 sys.path #返回模塊的搜索路徑,初始化時使用python PATH環境變量的值 5 sys.platform #返回操作系統平台的名稱 6 sys.stdin #輸入相關 7 sys.stdout #輸出相關 8 sys.stderror #錯誤相關
1 import sys,time 2 for i in range(1,20): 3 sys.stdout.write("#") #顯示寫入 4 time.sleep(0.2) 5 sys.stdout.flush() # 把每次寫入的東西都給刷新到屏幕

1 import sys,time 2 3 def view_bar(num, total): 4 rate = float(num) / float(total) 5 rate_num = int(rate * 100) 6 r = '\r%d%%' % (rate_num, ) #%% 表示一個% 7 sys.stdout.write(r) 8 sys.stdout.flush() 9 if __name__ == '__main__': 10 for i in range(0, 101): 11 time.sleep(0.1) 12 view_bar(i, 100)
1.3time模塊
在python中,通常3種時間的表示
1.時間戳(timestamp):時間戳表示的是從從1970年1月1日00:00:00開始按秒計算的偏移量。我們運行“type(time.time())”,返回的是float類型。
2.格式化的時間字符串 (年-月-日 時:分:秒)
3.元組(struct_time)結構化時間:struct_time元組共有9個元素共九個元素:(年,月,日,時,分,秒,一年中第幾周,一年中第幾天,夏令時)
常用time模塊方法
1 #注:小白多用print(),查看 2 3 1#time.time() 時間戳 4 print(time.time()) 5 6 2#time.localtime(second) 加上second(時間戳)轉換結構化時間,不加則顯示當前的結構化時間 7 print(time.localtime()) 8 print(time.localtime(1371643198)) 9 10 3#time.gmtime(second) #utc時區加上second(時間戳)轉換結構化時間,不加則顯示當前的結構化時間 11 print(time.gmtime()) 12 print(time.gmtime(1391614837)) 13 14 4#mktime ()結構化時間轉換為時間戳 15 print(time.mktime(time.localtime())) 16 17 5#time.ctime(seconds)#將加上時間戳轉換為時間戳的格式化時間,不加則返回當前的的格式化時間 18 print(time.time()) 19 print(time.ctime(1331644244)) 20 21 6#time.asctime(p_tuple)#加參數是加一個結構化時間,把加的結構化時間轉換為格式化時間,不加則返回當前的格式化時間 22 print(time.asctime()) 23 print(time.asctime(time.gmtime())) 24 25 7#time.strftime(format,p_tuple) #把一個結構化時間轉化相應的格式時間 26 print(time.strftime("%Y-%m-%d %X",time.localtime())) 27 28 8#time.strptime(string,format) #把相應的格式時間,轉換為結構化時間 29 print(time.strptime("2015-5-20 20:22:36","%Y-%m-%d %X")) 30 #time.struct_time(tm_year=2015, tm_mon=5, tm_mday=20, tm_hour=20, tm_min=22, tm_sec=36, tm_wday=2, tm_yday=140, tm_isdst=-1) 31 32 9#time.sleep(second)#將程序延遲指定的秒數運行 33 print(time.sleep(5)) 34 35 # 10 time.clock() 36 # 這個需要注意,在不同的系統上含義不同。在UNIX系統上,它返回的是“進程時間”,它是用秒表示的浮點數(時間戳)。 37 # 而在WINDOWS中,第一次調用,返回的是進程運行的實際時間。而第二次之后的調用是自第一次調用以后到現在的運行 38 # 時間,即兩次時間差。
1.4random模塊
1 import random 2 3 print(random.random())#隨機生成一個小於1的浮點數 4 5 print(random.randint(1,3)) #[1-3]隨機生成1到3的數 6 7 print(random.randrange(1,3)) #[1-3)隨機生成1到2的數 8 9 print(random.choice([1,'23',[4,5]]))#隨機在列表中選取一個元素 10 11 print(random.sample([1,'23',[4,5]],2))#隨機在列表中選取2個元素 12 13 print(random.uniform(1,3))#隨機生成1-3的之間的浮點數 14 15 print(random.shuffle([1,3,5,7,9]))#打亂列表中元素的順序

1 import random 2 3 def v_code(): 4 #隨機生成5位數的驗證碼 5 code = '' 6 for i in range(5): 7 num=random.randint(0,9) 8 alf=chr(random.randint(65,90)) 9 add=random.choice([num,alf]) 10 code += str(add) 11 return code 12 print(v_code())
1.5os模塊

1 os.getcwd() 獲取當前工作目錄,即當前python腳本工作的目錄路徑 2 os.chdir("dirname") 改變當前腳本工作目錄;相當於shell下cd 3 os.curdir 返回當前目錄: ('.') 4 os.pardir 獲取當前目錄的父目錄字符串名:('..') 5 os.makedirs('dirname1/dirname2') 可生成多層遞歸目錄 6 os.removedirs('dirname1') 若目錄為空,則刪除,並遞歸到上一級目錄,如若也為空,則刪除,依此類推 7 os.mkdir('dirname') 生成單級目錄;相當於shell中mkdir dirname 8 os.rmdir('dirname') 刪除單級空目錄,若目錄不為空則無法刪除,報錯;相當於shell中rmdir dirname 9 os.listdir('dirname') 列出指定目錄下的所有文件和子目錄,包括隱藏文件,並以列表方式打印 10 os.remove() 刪除一個文件 11 os.rename("oldname","newname") 重命名文件/目錄 12 os.stat('path/filename') 獲取文件/目錄信息 13 os.sep 輸出操作系統特定的路徑分隔符,win下為"\\",Linux下為"/" 14 os.linesep 輸出當前平台使用的行終止符,win下為"\t\n",Linux下為"\n" 15 os.pathsep 輸出用於分割文件路徑的字符串 win下為;,Linux下為: 16 os.name 輸出字符串指示當前使用平台。win->'nt'; Linux->'posix' 17 os.system("bash command") 運行shell命令,直接顯示 18 os.environ 獲取系統環境變量 19 os.path.abspath(path) 返回path規范化的絕對路徑 20 os.path.split(path) 將path分割成目錄和文件名二元組返回 21 os.path.dirname(path) 返回path的目錄。其實就是os.path.split(path)的第一個元素 22 os.path.basename(path) 返回path最后的文件名。如何path以/或\結尾,那么就會返回空值。即os.path.split(path)的第二個元素 23 os.path.exists(path) 如果path存在,返回True;如果path不存在,返回False 24 os.path.isabs(path) 如果path是絕對路徑,返回True 25 os.path.isfile(path) 如果path是一個存在的文件,返回True。否則返回False 26 os.path.isdir(path) 如果path是一個存在的目錄,則返回True。否則返回False 27 os.path.join(path1[, path2[, ...]]) 將多個路徑組合后返回,第一個絕對路徑之前的參數將被忽略 28 print(os.path.join("D:\\python\\wwww","xixi")) #做路徑拼接用的 29 #D:\python\wwww\xixi 30 31 os.path.getatime(path) 返回path所指向的文件或者目錄的最后存取時間 32 os.path.getmtime(path) 返回path所指向的文件或者目錄的最后修改時間
1.6json & pickle序列化模塊
JSON表示的對象就是標准的JavaScript語言的對象,JSON和Python內置的數據類型對應如下:
json和內置函數的eval()方法,eval將一個字符串轉成python對象,不過,eval 方法有局限性,對於普通的數據類型,json.loads和eval都能用,但遇到特殊類型的時候,eval就不管用了所以eval的重點還是通常用來執行一個字符串表達式,並返回表達式的值。
1 import json 2 aa = '{"name":"qa","age":11}' 3 xixi="[1,2,3,4,5,6]" 4 bb = "('1','2')" 5 print(eval(aa)) 6 print(json.loads(aa)) 7 print(type(json.loads(xixi))) 8 print(type(json.loads(aa))) 9 # print(type(json.loads(bb))) #報錯[](){}里面所有的元素的單引號必須改為雙引號,json不認單引號 10 11 xx = "[xixi,haha]" 12 # print(eval(xx)) #報錯 13 print(json.dumps(xx)) #"[xixi,haha]"
什么是序列化:
我們把對象(變量)從內存中變成可存儲或傳輸的過程稱之為序列化。
反過來,把變量內容從序列化的對象重新讀到內存里稱之為反序列化。
json:用於字符串和python數據類型間進行轉換。
pickle:用於python特有的類型和python的數據類型間進行轉換。
json的dumps,loads的功能:

1 import json 2 data = {'k1':123,'k2':456} 3 s_str=json.dumps(data) #把data對象序列化成字符串 >>>>>#序列化的過程 4 # print(s_str) #{"k2": 456, "k1": 123} 5 # print(type(s_str)) str 6 with open("js_new","w") as f: 7 f.write(s_str) #把json的字符串寫入到文件js_new 8 9 #注:用之前先把上面的寫文件的方式給注釋掉 10 with open("js_new","r") as f: 11 aa = json.loads(f.read()) #把字符串重新讀到python原來數據對象 >>>>#反序列化過程 12 print(aa) 13 # print(type(aa)) #<class 'dict'>
json的dump,load的功能

1 import json 2 data = {'k1':123,'k2':456} 3 with open("json_dump","w") as f: 4 json.dump(data,f) 5 #json.dump(x,f) x是python原來數據的對象,f是文件對象 主要是用來寫python對象到文件里面 6 7 with open("json_dump","r") as f: 8 bb = json.load(f) 9 print(bb) 10 print(type(bb)) #<class 'dict'> 11 #json.read(f) #f是文件對象,把文件對象的數據讀取成原來python對象的類型
json的dumps,loads,dump,load功能總結
json.dumps(x) 把python的(x)原對象轉換成json字符串的對象,主要用來寫入文件。
json.loads(f) 把json字符串(f)對象轉換成python原對象,主要用來讀取文件和json字符串
json.dump(x,f) 把python的(x)原對象,f是文件對象,寫入到f文件里面,主要用來寫入文件的
json.load(file) 把json字符串的文件對象,轉換成python的原對象,只是讀文件
pickle的功能
pickle和json的用法類似。
這里我就不一一舉列了

1 li = "[1,2,3,4,5,6,'aa']" 2 aa = pickle.dumps(li) 3 print(type(aa)) #<class 'bytes'> 4 # print(pickle.dumps(li)) #bytes對象 5 6 with open("pickle_new","wb") as p: #注意w是寫入str,wb時寫入字節 ,wb寫入文件是二進制, 7 # 我們看不到里面的里面寫入的文件內容pickle_new 8 pickle.dump(li,p) 9 with open("pickle_new","rb") as p_b: #以二進制方式讀取 10 # print(pickle.load(p_b)) #[1,2,3,4,5,6,'aa'] 11 print(pickle.loads(p_b.read())) #[1,2,3,4,5,6,'aa']
注:pickle的問題和所有其他編程語言特有的序列化的問題一樣,就是pickle它只能用於python,並且可能不同版本的python彼此都不兼容,因此,只能用pickle保存那些不重要的數據,不能成功的反序列化也沒關系。