python教程9、模組之sys,os,hashlib,random,time,datetime,logging,subprocess
python模組
用一砣程式碼實現了某個功能的程式碼集合。 類似於函數語言程式設計和麵向過程程式設計,函數語言程式設計則完成一個功能,其他程式碼用來呼叫即可,提供了程式碼的重用性和程式碼間的耦合。而對於一個複雜的功能來,可能需要多個函式才能完成(函式又可以在不同的.py檔案中),n個 .py 檔案組成的程式碼集合就稱為模組。模組分為內建模組、自定義的模組、安裝的第三方的模組
匯入模組
Python之所以應用越來越廣泛,在一定程度上也依賴於其為程式設計師提供了大量的模組以供使用,如果想要使用模組,則需要匯入。匯入模組有一下幾種方法:
1 2 3 4 |
import
module
from
module.xx.xx
import
xx
from
module.xx.xx
import
xx as rename
from module.xx.xx
import
*
|
匯入模組其實就是告訴Python直譯器去解釋那個py檔案
- 匯入一個py檔案,直譯器解釋該py檔案
- 匯入一個包,直譯器解釋該包下的 __init__.py 檔案
那麼問題來了,匯入模組時是根據那個路徑作為基準來進行的呢?即:sys.path
1 2 3 4 5 6 7 |
>>>
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('路徑') 新增。
1 2 3 4 |
import
sys
import
os
project_path
=
os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.append(project_path)
|
常用內建模組
內建模組是Python自帶的功能,在使用內建模組相應的功能時,需要【先匯入】再【使用】
一、sys
用於提供對Python直譯器相關的操作:
1 2 3 4 5 6 7 8 9 |
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 錯誤相關
|
進度條示例:
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)
二、os
用於提供系統級別的操作:
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 |
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命令,直接顯示,不能儲存執行結果<br>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所指向的檔案或者目錄的最後修改時間
|
三、hashlib
用於加密相關的操作,代替了md5模組和sha模組,主要提供 SHA1, SHA224, SHA256, SHA384, SHA512 ,MD5 演算法
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 |
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再來做加密。
1 2 3 4 5 6 7 |
import
hashlib
# ######## md5 ########
hash
=
hashlib.md5(bytes(
'898oaFs09f'
,encoding
=
"utf-8"
))
hash
.update(bytes(
'admin'
,encoding
=
"utf-8"
))
print
(
hash
.hexdigest())
|
四、random
1 2 3 4 5 6 7 8 9 10 11 12 |
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&datetime
時間相關的操作,時間有三種表示方式:
- 時間戳 1970年1月1日之後的秒,即:time.time()
- 格式化的字串 2014-11-11 11:11, 即:time.strftime('%Y-%m-%d')
- 結構化時間 元組包含了:年、日、星期等... time.struct_time 即:time.localtime()
time
1 2 3 4 5 6 7 8 9 10 11 12 13 |
import
time
print
(time.clock())
#返回處理器時間,3.3開始已廢棄
print
(time.process_time())
#返回處理器時間,3.3開始已廢棄<br>
print
(time.time())
#返回當前系統時間戳輸出:1471161757.5214906
print
(time.ctime())
#輸出字串格式時間:Sun Aug 14 16:04:02 2016 ,當前系統時間
print
(time.ctime(time.time()
-
86640
))
#將時間戳轉為字串格式<br>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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
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)
|
六、logging模組
很多程式都有記錄日誌的需求,並且日誌中包含的資訊即有正常的程式訪問日誌,還可能有錯誤、警告等資訊輸出,python的logging模組提供了標準的日誌介面,你可以通過它儲存各種格式的日誌,logging的日誌可以分為 debug()
, info()
, warning()
, error()
and critical() 5個級別,
下面我們看一下怎麼用。
日誌級別對應的數字:
1 |
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使用者輸出的訊息
1、單檔案日誌
1 2 3 4 5 6 7 8 9 10 11 12 13 |
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 mes
|