用一砣代碼實現了某個功能的代碼集合。 相似於函數式編程和麪向過程編程,函數式編程則完成一個功能,其餘代碼用來調用便可,提供了代碼的重用性和代碼間的耦合。而對於一個複雜的功能來,可能須要多個函數才能完成(函數又能夠在不一樣的.py文件中),n個 .py 文件組成的代碼集合就稱爲模塊。模塊分爲內建模塊、自定義的模塊、安裝的第三方的模塊html
Python之因此應用愈來愈普遍,在必定程度上也依賴於其爲程序員提供了大量的模塊以供使用,若是想要使用模塊,則須要導入。導入模塊有一下幾種方法:python
import module from module.xx.xx import xx from module.xx.xx import xx as rename from module.xx.xx import *
導入模塊其實就是告訴Python解釋器去解釋那個py文件linux
那麼問題來了,導入模塊時是根據那個路徑做爲基準來進行的呢?即:sys.path程序員
>>> import sys >>> print(sys.path) ['', '/home/tomcat/.pyenv/versions/3.5.1/lib/python35.zip', '/home/tomcat/.pyenv/versions/3.5.1/lib/python3.5', '/home/tomcat/.pyenv/versions/3.5.1/lib/python3.5/plat-linux', '/home/tomcat/.pyenv/versions/3.5.1/lib/python3.5/lib-dynload', '/home/tomcat/.pyenv/versions/3.5.1/lib/python3.5/site-packages']
若是sys.path路徑列表沒有你想要的路徑,能夠經過 sys.path.append('路徑') 添加。算法
import sys import os project_path = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) sys.path.append(project_path)
內置模塊是Python自帶的功能,在使用內置模塊相應的功能時,須要【先導入】再【使用】shell
用於提供對Python解釋器相關的操做:編程
sys.argv 命令行參數List,第一個元素是程序自己路徑 sys.exit(n) 退出程序,正常退出時exit(0) sys.version 獲取Python解釋程序的版本信息 sys.maxint 最大的Int值 sys.path 返回模塊的搜索路徑,初始化時使用PYTHONPATH環境變量的值 sys.platform 返回操做系統平臺名稱 sys.stdin 輸入相關 sys.stdout 輸出相關 sys.stderror 錯誤相關
進度條示例: windows
import sys
import time def view_bar(num,total): rate = num / total rate_num = int(rate * 100) r = '\r%s%d%%' % (">"*num,rate_num) sys.stdout.write(r) sys.stdout.flush() if __name__ == '__main__': for i in range(0, 100): time.sleep(0.1) view_bar(i, 100)
用於提供系統級別的操做:python3.x
os.getcwd() 獲取當前工做目錄,即當前python腳本工做的目錄路徑 os.chdir("dirname") 改變當前腳本工做目錄;至關於shell下cd os.curdir 返回當前目錄: ('.') os.pardir 獲取當前目錄的父目錄字符串名:('..') os.makedirs('dir1/dir2') 可生成多層遞歸目錄 os.removedirs('dirname1') 若目錄爲空,則刪除,並遞歸到上一級目錄,如若也爲空,則刪除,依此類推 os.mkdir('dirname') 生成單級目錄;至關於shell中mkdir dirname os.rmdir('dirname') 刪除單級空目錄,若目錄不爲空則沒法刪除,報錯;至關於shell中rmdir dirname os.listdir('dirname') 列出指定目錄下的全部文件和子目錄,包括隱藏文件,並以列表方式打印 os.remove() 刪除一個文件 os.rename("oldname","new") 重命名文件/目錄 os.stat('path/filename') 獲取文件/目錄信息 os.sep 操做系統特定的路徑分隔符,win下爲"\\",Linux下爲"/" os.linesep 當前平臺使用的行終止符,win下爲"\t\n",Linux下爲"\n" os.pathsep 用於分割文件路徑的字符串 os.name 字符串指示當前使用平臺。win->'nt'; Linux->'posix' os.system("bash command") 運行shell命令,直接顯示,不能保存執行結果
os.popen("bash command").read() 運行shell命令,能夠保存執行結果 os.environ 獲取系統環境變量 os.path.abspath(path) 返回path規範化的絕對路徑 os.path.split(path) 將path分割成目錄和文件名二元組返回 os.path.dirname(path) 返回path的目錄。其實就是os.path.split(path)的第一個元素 os.path.basename(path) 返回path最後的文件名。如何path以/或\結尾,那麼就會返回空值。即os.path.split(path)的第二個元素 os.path.exists(path) 若是path存在,返回True;若是path不存在,返回False os.path.isabs(path) 若是path是絕對路徑,返回True os.path.isfile(path) 若是path是一個存在的文件,返回True。不然返回False os.path.isdir(path) 若是path是一個存在的目錄,則返回True。不然返回False os.path.join(path1[, path2[, ...]]) 將多個路徑組合後返回,第一個絕對路徑以前的參數將被忽略 os.path.getatime(path) 返回path所指向的文件或者目錄的最後存取時間 os.path.getmtime(path) 返回path所指向的文件或者目錄的最後修改時間
用於加密相關的操做,代替了md5模塊和sha模塊,主要提供 SHA1, SHA224, SHA256, SHA384, SHA512 ,MD5 算法tomcat
import hashlib # ######## md5 ######## hash = hashlib.md5() # help(hash.update) hash.update(bytes('admin', encoding='utf-8')) print(hash.hexdigest()) print(hash.digest()) ######## sha1 ######## hash = hashlib.sha1() hash.update(bytes('admin', encoding='utf-8')) print(hash.hexdigest()) # ######## sha256 ######## hash = hashlib.sha256() hash.update(bytes('admin', encoding='utf-8')) print(hash.hexdigest()) # ######## sha384 ######## hash = hashlib.sha384() hash.update(bytes('admin', encoding='utf-8')) print(hash.hexdigest()) # ######## sha512 ######## hash = hashlib.sha512() hash.update(bytes('admin', encoding='utf-8')) print(hash.hexdigest())
以上加密算法雖然依然很是厲害,但時候存在缺陷,即:經過撞庫能夠反解。因此,有必要對加密算法中添加自定義key再來作加密。
import hashlib # ######## md5 ######## hash = hashlib.md5(bytes('898oaFs09f',encoding="utf-8")) hash.update(bytes('admin',encoding="utf-8")) print(hash.hexdigest())
import random print(random.random()) # 生成0-1之間的隨機小數 print(random.randint(1, 20)) #生成1到20的整數包括20 print random.uniform(10, 20) #生成10到20之間的浮點數 print(random.randrange(1, 10)) #生成1到10的證書不包括10,第3個參數能夠指定步長 print(random.choice(["JGood", "is", "a", "handsome", "boy"])) # 從序列中隨機選一個數 # 每次對序列隨機排序 p = ["Python", "is", "powerful", "simple"] random.shuffle(p) print(p)
隨機驗證碼
import random
li = [] for i in range(6): r = random.randint(0, 4) if r == 2 or r == 4: num = random.randrange(0, 10) li.append(str(num)) else: temp = random.randrange(65,91) c = chr(temp) li.append(c) result = "".join(li) print(result)
時間相關的操做,時間有三種表示方式:
time
import time print(time.clock()) #返回處理器時間,3.3開始已廢棄 print(time.process_time()) #返回處理器時間,3.3開始已廢棄
print(time.time()) #返回當前系統時間戳輸出:1471161757.5214906 print(time.ctime()) #輸出字符串格式時間:Sun Aug 14 16:04:02 2016 ,當前系統時間 print(time.ctime(time.time()-86640)) #將時間戳轉爲字符串格式
print(time.gmtime()) #獲取結構化時間 print(time.gmtime(time.time()-86640)) #將時間戳轉換成struct_time格式 print(time.localtime(time.time()-86640)) #將時間戳轉換成struct_time格式,但返回的本地時間 print(time.mktime(time.localtime())) #與time.localtime()功能相反,將struct_time格式轉回成時間戳格式 time.sleep(4) #睡上4秒 print(time.strftime("%Y-%m-%d %H:%M:%S",time.gmtime()) ) #將struct_time格式轉成指定的字符串格式 print(time.strptime("2016-01-28","%Y-%m-%d") ) #將字符串格式轉換成struct_time格式
datetime
import datetime print(datetime.date.today()) #輸出格式 2016-01-26 print(datetime.date.fromtimestamp(time.time()-864400) ) #2016-01-16 將時間戳轉成日期格式 current_time = datetime.datetime.now() # print(current_time) #輸出2016-01-26 19:04:30.335935 print(current_time.timetuple()) #返回struct_time格式 #datetime.replace([year[, month[, day[, hour[, minute[, second[, microsecond[, tzinfo]]]]]]]]) print(current_time.replace(2014,9,12)) #輸出2014-09-12 19:06:24.074900,返回當前時間,但指定的值將被替換 str_to_date = datetime.datetime.strptime("21/11/06 16:30", "%d/%m/%y %H:%M") #將字符串轉換成日期格式 new_date = datetime.datetime.now() + datetime.timedelta(days=10) #比如今加10天 new_date = datetime.datetime.now() + datetime.timedelta(days=-10) #比如今減10天 new_date = datetime.datetime.now() + datetime.timedelta(hours=-10) #比如今減10小時 new_date = datetime.datetime.now() + datetime.timedelta(seconds=120) #比如今+120s print(new_date)
不少程序都有記錄日誌的需求,而且日誌中包含的信息即有正常的程序訪問日誌,還可能有錯誤、警告等信息輸出,python的logging模塊提供了標準的日誌接口,你能夠經過它存儲各類格式的日誌,logging的日誌能夠分爲 debug()
, info()
, warning()
, error()
and critical() 5個級別,
下面咱們看一下怎麼用。
日誌級別對應的數字:
CRITICAL = 50 ERROR = 40 WARNING = 30 INFO = 20 DEBUG = 10 NOTSET = 0
日誌記錄格式:
%(name)s Logger的名字
%(levelno)s 數字形式的日誌級別
%(levelname)s 文本形式的日誌級別
%(pathname)s 調用日誌輸出函數的模塊的完整路徑名,可能沒有
%(filename)s 調用日誌輸出函數的模塊的文件名
%(module)s 調用日誌輸出函數的模塊名
%(funcName)s 調用日誌輸出函數的函數名
%(lineno)d 調用日誌輸出函數的語句所在的代碼行
%(created)f 當前時間,用UNIX標準的表示時間的浮 點數表示
%(relativeCreated)d 輸出日誌信息時的,自Logger建立以 來的毫秒數
%(asctime)s 字符串形式的當前時間。默認格式是 「2003-07-08 16:49:45,896」。逗號後面的是毫秒
%(thread)d 線程ID。可能沒有
%(threadName)s 線程名。可能沒有
%(process)d 進程ID。可能沒有
%(message)s用戶輸出的消息
一、單文件日誌
import logging logging.basicConfig(level=logging.DEBUG, format='%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s', datefmt='%Y-%m-%d %H:%M:%S %p', filename='test.log', filemode='w') logging.debug('debug message') logging.info('info message') logging.warning('warning message') logging.error('error message') logging.critical('critical message')
二、多文件日誌
對於上述記錄日誌的功能,只能將日誌記錄在單文件中,若是想要設置多個日誌文件,logging.basicConfig將沒法完成,須要自定義文件和日誌操做對象。
#!/usr/bin/env python # -*- coding:utf-8 -*- import logging #獲取日誌器對象 logger = logging.getLogger('TEST-LOG') # 返回一個logger對象,沒有指定的話默認是root logger logger.setLevel(logging.DEBUG) #設置全局日誌級別 #定義屏幕控制器把日誌輸出屏幕 ch = logging.StreamHandler() ch.setLevel(logging.DEBUG) # 輸出屏幕的日誌級別 formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s') ch.setFormatter(formatter) # 給輸出屏幕的日誌設置日誌格式 logger.addHandler(ch) # 將設定好的控制器添加到日誌器中 #定義文件控制器把日誌輸出文件 fh = logging.FileHandler("access.log") fh.setLevel(logging.WARNING) #設置輸出文件的日誌級別 formatter1 = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s') fh.setFormatter(formatter1) # 給輸出文件的日誌設置日誌格式 logger.addHandler(fh) # 將設定好的控制器添加到日誌器中 logger.debug('debug message') logger.info('info message') logger.warn('warn message') logger.error('error message') logger.critical('critical message')
注意:局部日誌級別只有大於全局日誌級別纔會記錄
能夠執行shell命令的相關模塊和函數有:
一、os.system()
>>> import os >>> os.system('ls') a.py b.py Desktop myenv35 PycharmProjects workplace a.txt b.txt myenv27 pass.py scripts 0
二、os.popen().read()
>>> import os >>> fi = os.popen('ls').read() >>> print(fi) a.py a.txt b.py b.txt
三、commands(在python2.x中執行)
>>> import commands >>> result = commands.getoutput('ls') >>> print(result) a.py a.txt b.py b.txt >>> result1 = commands.getstatusoutput('ls') >>> print(result1) (0, 'a.py\na.txt\nb.py\nb.txt\nDesktop\nmyenv27\nmyenv35\npass.py\nPycharmProjects\nscripts\nworkplace')
四、subprocess
subprocess.call() 執行命令,返回狀態碼,shell=False,第一個參數必須是列表,shell=True,第一個參數就直接輸入命令便可
>>> ret = subprocess.call(["ls", "-l"], shell=False)
或: >>> ret = subprocess.call("ls -l", shell=True)
subprocess.check_call() 執行命令,若是執行狀態碼是 0 ,則返回0,不然拋異常
>>> ret = subprocess.check_call(["ls", "-l"],shell=False)
>>> print(ret) >>> ret = subprocess.check_call("exit 1", shell=True)
>>> print(ret)
subprocess.check_output() 執行命令,若是狀態碼是 0 ,則返回執行結果,不然拋異常,注意這裏返回的是字節類型,須要轉換
>>> ret = subprocess.check_output(["echo", "Hello World!"],shell=False)
>>> print(str(ret,encoding='utf-8'))
或 >>> ret = subprocess.check_output("exit 1", shell=True)
>>> print(str(ret,encoding='utf-8'))
subprocess.run() python3.5新加的功能,代替os.system,os.spawn
>>> import subprocess >>> subprocess.run(["ls", "-l"]) total 56 -rw-rw-r-- 1 tomcat tomcat 61 8月 11 23:27 a.py -rw-rw-r-- 1 tomcat tomcat 12929 8月 8 18:03 a.txt CompletedProcess(args=['ls', '-l'], returncode=0) >>> subprocess.run(["ls", "-l", "/dev/null"], stdout=subprocess.PIPE) CompletedProcess(args=['ls', '-l', '/dev/null'], returncode=0, stdout=b'crw-rw-rw- 1 root root 1, 3 8\xe6\x9c\x88 11 09:27 /dev/null\n')
subprocess.Popen() 用於執行復雜的系統命令,是上面方法的底層實現
調用subprocess.run(...)是推薦的經常使用方法,在大多數狀況下能知足需求,但若是你可能須要進行一些複雜的與系統的交互的話,你還能夠用subprocess.Popen(),語法以下:
p = subprocess.Popen("find ~/ -size +1000 -exec ls -shl {} \;",shell=True,stdout=subprocess.PIPE) print(p.stdout.read())
參數:
終端輸入的命令分爲兩種:
(1)輸入便可獲得輸出
import subprocess obj = subprocess.Popen(["mkdir","test"],cwd='/tmp/',) 或者 obj1 = subprocess.Popen("mkdir test1", shell=True, cwd='/tmp/',)
(2)輸入進行某環境,依賴再輸入,經過輸入,輸出,錯誤管道,輸入數據,獲取數據
import subprocess obj = subprocess.Popen(["python"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True) obj.stdin.write("print(1)\n") obj.stdin.write("print(2)") obj.stdin.close() cmd_out = obj.stdout.read() obj.stdout.close() cmd_error = obj.stderr.read() obj.stderr.close() print(cmd_out) print(cmd_error) 或者 obj = subprocess.Popen(["python"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True) obj.stdin.write("print(1)\n") obj.stdin.write("print(2)") out_error_list = obj.communicate() print(out_error_list) 或者 obj = subprocess.Popen(["python"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True) out_error_list = obj.communicate('print("hello")') print(out_error_list)