Python【第五篇】模塊、包、經常使用模塊

1、模塊(Module)

在計算機程序的開發過程當中,隨着程序代碼越寫越多,在一個文件裏代碼就會愈來愈長,愈來愈不容易維護。python

爲了編寫可維護的代碼,咱們把不少函數分組,分別放到不一樣的文件裏,這樣,每一個文件包含的代碼就相對較少,不少編程語言都採用這種組織代碼的方式。在Python中,一個.py文件就稱之爲一個模塊(Module)。linux

使用模塊的好處:正則表達式

  • 最大的好處是大大提升了代碼的可維護性。其次,編寫代碼沒必要從零開始。當一個模塊編寫完畢,就能夠被其餘地方引用。咱們在編寫程序的時候,也常常引用其餘模塊,包括Python內置的模塊和來自第三方的模塊。
  • 使用模塊還能夠避免函數名和變量名衝突。每一個模塊有獨立的命名空間,所以相同名字的函數和變量徹底能夠分別存在不一樣的模塊中,因此,咱們本身在編寫模塊時,沒必要考慮名字會與其餘模塊衝突

模塊分類算法

模塊分爲三種:shell

  • 內置標準模塊(又稱標準庫)執行help('modules')查看全部python自帶模塊列表
  • 第三方開源模塊,可經過pip install 模塊名 聯網安裝
  • 自定義模塊

模塊調用數據庫

import module
from module import xx
from module.xx.xx import xx

注意:模塊一旦被調用,即至關於執行了另一個py文件裏的代碼 編程

模塊安裝json

最經常使用的模塊安裝方式就是pip安裝了,python3 -m pip install 模塊名flask

模塊被安裝在python安裝目錄下的Lib\site-packages,好比個人安裝在這個目錄:C:\Python36\Lib\site-packageswindows

若是是由於網速問題,超時了,能夠加大pip安裝時候的超時時間,設置爲1000秒,pip --default-timeout=1000 install selenium==2.53.6 

固然,咱們也能夠更換模塊安裝源:

pip3 install --index-url https://pypi.douban.com/simple selenium==2.53.6

python3 -m pip install --index-url https://pypi.doubanio.com/simple/ flask --trusted-host pypi.douban.com

python3 -m pip install -i https://pypi.doubanio.com/simple/ flask --trusted-host pypi.douban.com

2、包(Package)

當你的模塊文件愈來愈多,就須要對模塊文件進行劃分,好比把負責跟數據庫交互的都放一個文件夾,把與頁面交互相關的放一個文件夾

.
└── my_project
    ├── mobileBank #代碼目錄
    │   ├── admin.py
    │   ├── apps.py
    │   ├── models.py
    │   ├── tests.py
    │   └── views.py
    ├── manage.py
    └── my_proj #配置文件目錄
        ├── settings.py
        ├── urls.py
        └── wsgi.py

像上面這樣,一個文件夾管理多個模塊文件,這個文件夾就被稱爲包;

注意,在python3裏,即便目錄下沒__int__.py文件也能建立成功,猜應該是解釋器優化所致,但建立包仍是要記得加上這個文件 吧。

根據上面的結構,如何實如今crm/views.py裏導入proj/settings.py模塊?直接導入的話,會報錯,說找到不模塊。

添加環境變量,把父親級的路徑添加到sys.path中,就能夠了,這樣導入 就至關於從父親級開始找模塊了。

import sys ,os

BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) #__file__的是打印當前被執行的模塊.py文件相對路徑,注意是相對路徑
print(BASE_DIR)

sys.path.append(BASE_DIR)  

3、經常使用模塊

os

os 模塊提供了不少容許你的程序與操做系統直接交互的功能

os.getcwd() 獲取當前工做目錄,即當前python腳本工做的目錄路徑(實際上是py解釋器啓動的目錄)
os.chdir("dirname")  改變當前腳本工做目錄;至關於shell下cd
os.curdir  返回當前目錄: ('.'),注意,os.curdir後面沒有括號
os.pardir  獲取當前目錄的父目錄字符串名:('..')
os.makedirs('dirname1/dirname2')  可生成多層遞歸目錄,os.makedirs('dirname1\dirname2') 也能夠,可是最好前面加上r
os.removedirs('dirname1')    若目錄爲空,則刪除,並遞歸到上一級目錄,如若也爲空,則刪除,依此類推
os.mkdir('dirname')    生成單級目錄;至關於shell中mkdir dirname
os.rmdir('dirname')    刪除單級空目錄,若目錄不爲空則沒法刪除,報錯;至關於shell中rmdir dirname
os.listdir('dirname')    列出指定目錄下的全部文件和子目錄,包括隱藏文件,並以列表方式打印
os.walk和os.listdir的結果同樣(目錄在只有文件,包含目錄的狀況待測試)
os.walk() 經過在目錄樹種遊走輸出在目錄中的文件名,向上或者向下。產生一個三個元素的元組 (dirpath, dirnames, filenames),分別是文件夾路徑, 文件夾名字, 文件名,
os.remove()  刪除一個文件,參數寫上文件路徑
os.rename("oldname","newname")  重命名文件/目錄,和os.renames("oldname","newname")、os.replace("oldname","newname")功能相同,至關於能夠實現文件的重命名,文件的移動,文件的移動並重命名,
os.rename(r'F:\practice\m2\123-2.txt', r'F:\practice\m1\123.txt')
os.stat('path/filename')  獲取文件/目錄信息,返回一個類,其中文件大小屬性是filesize,和getsize同樣,獲得的是文件的字節數
os.sep    輸出操做系統特定的路徑分隔符,win下爲"\\",Linux下爲"/"
os.linesep    輸出當前平臺使用的行終止符(換行),win下爲"\r\n",Linux和MAC下爲"\n"
os.pathsep    輸出用於分割文件路徑的字符串 win下爲分號;,Linux下爲冒號:
os.name    輸出字符串指示當前使用平臺。win->'nt'; Linux->'posix'
os.system("bash command")  運行shell命令,直接顯示,如os.system('dir'),命令執行成功,在結果下還會返回0,命令執行不成功,返回非0
os.getenv('HOME') 讀取操做系統環境變量HOME的值
os.environ  獲取系統環境變量
os.environ.setdefault('HOME','/home/wgy') 設置系統環境變量,僅程序運行時有效
os.chmod(file) 修改文件權限與時間戳
os.get_terminal_size() 獲取當前終端的大小,調整終端窗口大小,行列值跟着變化
os.kill(10884,signal.SIGKILL) 殺死進程10884
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.isabs(path)  若是path是絕對路徑,返回True,windows有多個根,好比c:\,d:\,linux只有一個根/
os.path.exists(path)  若是path存在,返回True;若是path不存在,返回False
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所指向的文件或者目錄的最後修改時間,返回時間戳
os.path.getsize(path) 返回path的大小(返回的是文件中字節個數,數字和英文是1個字節,中文是3個字節)

sys

sys.exit(n) # 退出程序,正常退出時exit(0)
sys.version # 獲取Python解釋程序的版本信息
sys.maxint # 最大的Int值(py2),py3中爲sys.maxsize
sys.path  # 返回模塊的搜索路徑,初始化時使用PYTHONPATH環境變量的值
sys.platform  # 返回操做系統平臺名稱
sys.stdout.write('please:')  # 標準輸出 , 引出進度條的例子, 注,在py3上不行,能夠用print代替
sys.stdin.read() # 會一直等待用戶輸入,哪怕用戶輸入了,只能ctrl+c結束
sys.getrecursionlimit() # 獲取最大遞歸層數
sys.setrecursionlimit(1200) # 設置最大遞歸層數
sys.getdefaultencoding()  # 獲取解釋器默認編碼
sys.getfilesystemencoding  # 獲取內存數據存到文件裏的默認編碼
sys.modules  # 是一個dictionary,表示系統中全部可用的module,面向對象中, 反射會用到

time

在Python中,一般有這幾種方式來表示時間:時間戳、格式化的時間字符串、元組(struct_time)共九個元素。因爲Python的time模塊實現主要調用C庫,因此各個平臺可能有所不一樣。

幾個定義:

  UTC(Coordinated Universal Time,世界協調時)亦即格林威治天文時間,世界標準時間。在中國爲UTC+8。DST(Daylight Saving Time)即夏令時。

  時間戳(timestamp)的方式:一般來講,時間戳表示的是從1970年1月1日00:00:00開始按秒計算的偏移量。咱們運行「type(time.time())」,返回的是float類型。

  元組(struct_time)方式:struct_time元組共有9個元素,返回struct_time的函數主要有gmtime(),localtime(),strptime()。下面列出這種方式元組中的幾個元素:

索引(Index)    屬性(Attribute)    值(Values)
0     tm_year(年)                 好比2011 
1     tm_mon(月)             1 - 12
2     tm_mday(日)                 1 - 31
3     tm_hour(時)                 0 - 23
4     tm_min(分)             0 - 59
5     tm_sec(秒)             0 - 61
6     tm_wday(weekday)            0 - 6(0表示週日)
7     tm_yday(一年中的第幾天)    1 - 366
8     tm_isdst(是不是夏令時)            默認爲-1

經常使用方法

time.localtime([secs]):將一個時間戳轉換爲當前時區的struct_time。secs參數未提供,則以當前時間爲準。
time.gmtime([secs]):和localtime()方法相似,gmtime()方法是將一個時間戳轉換爲UTC時區(0時區)的struct_time。
time.time():返回當前時間的時間戳。
time.mktime(t):將一個struct_time轉化爲時間戳。
time.sleep(secs):線程推遲指定的時間運行。單位爲秒。
time.asctime([t]):把一個表示時間的元組或者struct_time表示爲這種形式:'Wed Jun 14 12:36:17 2017'。若是沒有參數,將會將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()返回)轉化爲格式化的時間字符串。若是t未指定,將傳入time.localtime()。

示例:

import time
print(time.time())
print(time.ctime())
print(time.localtime())
print(time.strftime('%Y_%m_%d %H:%M:%S'))

1497414977.1362307
Wed Jun 14 12:36:17 2017
time.struct_time(tm_year=2017, tm_mon=6, tm_mday=14, tm_hour=12, tm_min=36, tm_sec=17, tm_wday=2, tm_yday=165, tm_isdst=0)
2017_06_14 12:36:17

datetime

相比於time模塊,datetime模塊的接口則更直觀、更容易調用

datetime.date:表示日期的類。經常使用的屬性有year, month, day;
datetime.time:表示時間的類。經常使用的屬性有hour, minute, second, microsecond;
datetime.datetime:表示日期時間。
datetime.timedelta:表示時間間隔,即兩個時間點之間的長度。
datetime.tzinfo:與時區有關的相關信息。

random

程序中有不少地方須要用到隨機字符,好比登陸網站的隨機驗證碼,經過random模塊能夠很容易生成隨機字符串。

import random
print(random.random())  # (0,1)----float    大於0且小於1之間的小數
print(random.randint(1, 3))  # [1,3]    大於等於1且小於等於3之間的整數,包含3
print(random.randrange(1, 3))  # [1,3)    大於等於1且小於3之間的整數,不包含3
print(random.choice([1, '23', [4, 5]]))  # 1或者23或者[4,5],返回一個給定數據集合中的隨機元素
print(random.choice('abcde'))
print(random.sample([1, '23', [4, 5]], 2))  # 列表元素任意2個組合,返回一個列表
print(random.sample('python', 3)) # 返回一個列表

'''
0.8069726390185565
2
1
1
d
[[4, 5], '23']
['y', 'p', 'o']
'''

hashlib

hashlib是一個加密模塊,提供了常見的加密算法,好比MD5,SHA1,SHA256等,它經過一個函數,把任意長度的數據轉換爲一個長度固定的數據串,經常使用來保存密碼等,好比將用戶的密碼用MD5加密後,保存到數據庫,用戶登陸時先計算用戶輸入的明文口令的MD5,而後和數據庫存儲的MD5對比,若是一致,說明密碼輸入正確,若是不一致,密碼確定錯誤。

import hashlib

passwd = hashlib.sha256()
passwd.update('123456'.encode('utf-8'))  # 假設密碼是123456 將其轉換爲字節,傳入函數
print(passwd.hexdigest())  # 8d969eef6ecad3c29a3a629280e686cf0c3f5d5a86aff3ca12020c923adc6c92

passwd = hashlib.sha256('UncleYong'.encode('utf-8'))  # 對原始密碼加一個複雜字符串來提升安全性,俗稱「加鹽」
print(passwd.hexdigest())  # 66d184cfeedb54b8f0e7819e01a2ab28ec7038ff7677716740c7e0d1962f84b1
passwd.update('123456'.encode('utf-8'))  # d217b3c0f274dbaf8fe145df567a9f53df056527d01b541bb1a6997373485f26
print(passwd.hexdigest())

re

正則表達式就是字符串的匹配規則,在多數編程語言裏都有相應的支持,python裏對應的模塊是re

'.'     默認匹配除\n以外的任意一個字符,若指定flag DOTALL,則匹配任意字符,包括換行
'^'     匹配字符開頭,若指定flags MULTILINE,這種也能夠匹配上(r"^a","\nabc\neee",flags=re.MULTILINE)
'$'     匹配字符結尾, 若指定flags MULTILINE ,re.search('foo.$','foo1\nfoo2\n',re.MULTILINE).group() 會匹配到foo1
'*'     匹配*號前的字符0次或屢次, re.search('a*','aaaabac')  結果'aaaa'
'+'     匹配前一個字符1次或屢次,re.findall("ab+","ab+cd+abb+bba") 結果['ab', 'abb']
'?'     匹配前一個字符1次或0次 ,re.search('b?','jack').group() 匹配b 0次
'{m}'   匹配前一個字符m次 ,re.search('b{3}','jackxbbbs').group()  匹配到'bbb'
'{n,m}' 匹配前一個字符n到m次,re.findall("ab{1,3}","abb abc abbcbbb") 結果'abb', 'ab', 'abb']
'|'     匹配|左或|右的字符,re.search("abc|ABC","ABCBabcCD").group() 結果'ABC'
'(...)' 分組匹配, re.search("(abc){2}a(123|45)", "abcabca456c").group() 結果爲'abcabca45'


'\A'    只從字符開頭匹配,re.search("\Aabc","jackabc") 是匹配不到的,至關於re.match('abc',"jackabc") 或^
'\Z'    匹配字符結尾,同$ 
'\d'    匹配數字0-9
'\D'    匹配非數字
'\w'    匹配[A-Za-z0-9]
'\W'    匹配非[A-Za-z0-9]
's'     匹配空白字符、\t、\n、\r , re.search("\s+","ab\tc1\n3").group() 結果 '\t'

json

若是要在不一樣的平臺間傳遞信息的話,就能夠用到Json模塊,json用於字符串 和 python數據類型間進行轉換,只能支持int\str\list\tuple\dict

json提供了四個功能:dumps、dump、loads、load

json:dumps & loads

import json
data = {'k1':123,'k2':'Hello'}
# json.dumps 將數據經過特殊的形式轉換爲全部程序語言都認識的字符串
j_str = json.dumps(data)
print(j_str, type(j_str))
res = json.loads(j_str)
print(res, type(res))

'''
{"k1": 123, "k2": "Hello"} <class 'str'>
{'k1': 123, 'k2': 'Hello'} <class 'dict'>
'''

json:dump

import json
data = {'k1':123,'k2':'Hello'}
# json.dump 將數據經過特殊的形式轉換爲全部程序語言都認識的字符串,並寫入文件
json.dump(data,open('D:/result.json','w'))

json:load

import json
res = json.load(open('D:/result.json', 'r'))
print(res,type(res))

'''
{'k1': 123, 'k2': 'Hello'} <class 'dict'>
'''

logging

logging是用來紀錄日誌的模塊,能夠自動幫咱們紀錄程序運行中出現的錯誤,出了問題能夠方便咱們後來去日誌中查找緣由,在實際開發中很是好用。

日誌級別

日誌格式

import logging

class IgnoreBackupLogFilter(logging.Filter):
    def filter(self, record):  # 固定寫法
        return "db backup" not in record.getMessage()

logger = logging.getLogger('my_log')

logger.addFilter(IgnoreBackupLogFilter())

sh = logging.StreamHandler()
sh.setLevel(logging.INFO)

fh = logging.FileHandler('test.log', mode='a', encoding='utf-8')
fh.setLevel(logging.INFO)

logger.addHandler(sh)
logger.addHandler(fh)

formater = logging.Formatter('%(asctime)s - %(pathname)s[line:%(lineno)d] - %(levelname)s: %(message)s')
sh.setFormatter(formater)
fh.setFormatter(formater)

logger.debug('debug級別,最低級別,http://www.cnblogs.com/UncleYong/')
logger.info('info級別,正常輸出信息,http://www.cnblogs.com/UncleYong/')
logger.warning('waring級別,http://www.cnblogs.com/UncleYong/')
logger.error('error級別,http://www.cnblogs.com/UncleYong/')
logger.critical('critical級別,http://www.cnblogs.com/UncleYong/,db backup')

4、練習(加Q羣獲取參考答案)

1.利用內置函數chr(),ord()以及random模塊寫一個簡單隨機4位驗證碼。

相關文章
相關標籤/搜索