Python基礎之模組

2023-01-20 18:00:23

Python基礎之模組

一、關於模組的基礎知識

1.模組的本質

  • 內部具有一定功能的py檔案

2.模組的分類

  • 自定義模組 程式設計師自己寫的模組檔案
  • 內建模組 Python直譯器提供的模組
  • 第三模組 別的程式設計師模組檔案(Python背後真正的大佬)

2.兩種匯入模組的語句及判斷執行檔案語句

# 用來相對匯入
import
# 用來絕對匯入
from ··· import···
# 用來判斷是否執行檔案
if __name__ == '__main__':
    print('哈哈哈 我是執行檔案 我可以執行這裡的子程式碼')

二、Python常見內建模組

1.collections模組

1.具名元組:namedtuple
from collections import namedtuple
# 能表示二維座標 如:點(1,2)
point = namedtuple('點', ['x', 'y'])
card = namedtuple('撲克牌', ['num', 'color'])
c1 = card('A', '黑♠')
c2 = card('A', '紅♥')
print(c1, c1.num, c1.color)
print(c2, c2.num, c2.color)

'''
列印結果如下
撲克牌(num='A', color='黑♠') A 黑♠
撲克牌(num='A', color='紅♥') A 紅♥
'''
2.佇列與堆疊
佇列:先進先出
堆疊:先進後出
# 佇列和堆疊都是一邊只能出一邊進

2.time時間模組

時間的三種表現形式

  • 時間戳 time.time() 可以得到的是 時間戳 。即 1970年1月1日0時0分0秒到現在時間的偏移量 s
  • 結構化時間 time.struct_time() 主要是給計算機看的 人看不適應
  • 格式化時間 time.strftime()
time.time()  # 時間戳  1674137513.8003848
time.strftime('%Y-%m-%d %H:%M:%S %X') # %H:%M:%S與%X意思一樣都可以獲取時分秒
time.localtime()  # 以結構化時間的格式列印當地時間
time.sleep(10)  # 讓程式原地休息10秒

3.datetime時間模組

datetime.datetime.now()  # 2023-01-19 22:21:13.199755 年月日時分秒 
datetime.datetime.today()  # 2023-01-19 22:22:05.770036 年月日時分秒
datetime.date.today()  # 2023-01-19	年月日
datetime.timedelta(days=3)  # 3 days, 0:00:00 時間差值

4.random隨機模組

random.random()  # 隨機產生0到1之間的小數
random.randint(1, 6)  # 隨機產生1到6之間的整數
random.randrange()  # 隨機產生範圍
random.choice()  # 隨機抽取一個 抽獎的 '一等獎'
random.choices()  # 隨機抽取一個 抽獎的 ['一等獎']
random.sample()  # 可以指定一次抽取幾個樣本
random.shuffle()  # 類似於洗牌 給出一個列表 每次都會隨機打亂列表裡面資料值的順序

5.os模組 主要與程式碼執行所在的作業系統打交道

# 1.建立目錄(資料夾)
os.mkdir(r'd1')  # 相對路徑 在執行檔案所在的路徑下建立目錄 可以建立單級目錄不可以建立多級目錄
os.makedirs(r'd2\d22\d222')  # 可以建立多級目錄 也可以建立單級目錄
# 2.刪除目錄(資料夾)
os.rmdir(r'd1')  # 只能刪空的單級目錄 不可以一次性刪除多級目錄
os.removedirs(r'd2\d22')  # 可以刪除多級目錄 只能刪除空的多級目錄
# 3.列舉指定路徑下內容名稱
os.listdir()
os.listdir(r'D:\\')
# 4.刪除/重新命名檔案
os.rename(r'a.txt', r'aaa.txt')
os.remove(r'aaa.txt')
# 5.獲取/切換當前工作目錄
print(os.getcwd())  # D:\pythonProject03\day19
os.chdir('..')  # 切換到上一級目錄
print(os.getcwd())  # D:\pythonProject03
os.mkdir(r'hei')
# 6.動態獲取專案根路徑(重要)
os.path.abspath(__file__)  # 獲取執行檔案的絕對路徑  
os.path.dirname(__file__) # 獲取執行檔案所在的目錄路徑 
# 7.判斷路徑是否存在(檔案、目錄)
os.path.exists()   
os.path.isfile()  
os.path.isdir() 
# 8.路徑拼接(重要)
os.path.join()
# 9.獲取檔案大小(位元組)
print(os.path.getsize(r'a.txt'))

6.sys模組 主要與python直譯器打交道

sys.path  # 獲取執行檔案的sys.path路徑
sys.getrecursionlimit()  # 獲取Python直譯器預設最大遞迴深度
sys.setrecursionlimit(2000)  #修改Python預設最大遞迴深度
sys.version  # 獲取當前直譯器的版本資訊
sys.platform  # 可以獲取平臺資訊  win32 

7.json序列化模組 序列化可以打破語言限制實現不同程式語言之間資料互動

# json格式資料的形式
字串型別並且引號都是雙引號
針對資料
json.dumps()  # 序列化 字典型別轉換為json格式
json.loads()  # 反序列化 json格式轉換為字典型別
針對檔案
json.dump()
json.load()
d = {'name': 'jason老師', 'pwd': 123}
# json模組針對中文不會自動轉碼 
res = json.dumps(d, ensure_ascii=False)
print(res)

8.hashlib加密模組

# 何為加密
將明文資料處理成密文資料 讓人無法看懂
加密演演算法不變 內容如果相同 那麼結果肯定相同

# 為什麼加密
保證資料的安全

# 如何判斷資料是否是加密的
一串沒有規律的字串(數位、字母、符號)
加密之後的結果是無法反解密的

# 密文的長短有何講究
密文越長表示使用的加密演演算法(資料的處理過程)越複雜

# 常見的加密演演算法有哪些
md5、base64、hmac、sha系列

# 動態加鹽
干擾項是隨機變化的 eg:當前時間、使用者名稱部分...
'''加密基本操作'''
import hashlib
# 1.選擇加密演演算法
md5 = hashlib.md5()
# 2.傳入明文資料
md5.update(b'hello')
# 3.獲取加密密文
res = md5.hexdigest()
print(res)  # 5d41402abc4b2a76b9719d911017c592
'''加密加鹽處理操作'''
# 1.選擇加密演演算法
md5 = hashlib.md5()
# 2.傳入明文資料
md5.update('公司設定的干擾項'.encode('utf8'))
md5.update(b'hello python')  # 一次性傳可以
# 3.獲取加密密文
res = md5.hexdigest()
print(res)  # e53024684c9be1dd3f6114ecc8bbdddc

9.subprocess模組 模擬作業系統終端 執行命令並獲取結果

import subprocess

res = subprocess.Popen(
    'asdas',  # 作業系統要執行的命令
    shell=True,  # 固定設定
    stdin=subprocess.PIPE,  # 輸入命令
    stdout=subprocess.PIPE,  # 輸出結果
)
print('正確結果', res.stdout.read().decode('gbk'))  # 獲取作業系統執行命令之後的正確結果
print('錯誤結果', res.stderr)  # 獲取作業系統執行命令之後的錯誤結

10.logging紀錄檔模組

# 紀錄檔的組成
產生紀錄檔
過濾紀錄檔
輸出紀錄檔
紀錄檔格式

# 如何理解紀錄檔
紀錄檔就是記錄行為舉止的操作

# 紀錄檔的級別
有五種級別 程式碼不需要掌握 會CV並稍作修改即可
import logging
# logging.debug('debug message')
# logging.info('info message')
# logging.warning('warning message')
# logging.error('error message')
# logging.critical('critical message')
file_handler = logging.FileHandler(filename='x1.log', mode='a', encoding='utf8',)
logging.basicConfig(
    format='%(asctime)s - %(name)s - %(levelname)s -%(module)s:  %(message)s',
    datefmt='%Y-%m-%d %H:%M:%S %p',
    handlers=[file_handler,],
    level=logging.ERROR
)

logging.error('你好')
import logging

# 1.紀錄檔的產生(準備原材料)        logger物件
logger = logging.getLogger('購物車記錄')
# 2.紀錄檔的過濾(剔除不良品)        filter物件>>>:可以忽略 不用使用
# 3.紀錄檔的產出(成品)             handler物件
hd1 = logging.FileHandler('a1.log', encoding='utf-8')  # 輸出到檔案中
hd2 = logging.FileHandler('a2.log', encoding='utf-8')  # 輸出到檔案中
hd3 = logging.StreamHandler()  # 輸出到終端
# 4.紀錄檔的格式(包裝)             format物件
fm1 = logging.Formatter(
        fmt='%(asctime)s - %(name)s - %(levelname)s -%(module)s:  %(message)s',
        datefmt='%Y-%m-%d %H:%M:%S %p',
)
fm2 = logging.Formatter(
        fmt='%(asctime)s - %(name)s:  %(message)s',
        datefmt='%Y-%m-%d',
)
# 5.給logger物件繫結handler物件
logger.addHandler(hd1)
logger.addHandler(hd2)
logger.addHandler(hd3)
# 6.給handler繫結formmate物件
hd1.setFormatter(fm1)
hd2.setFormatter(fm2)
hd3.setFormatter(fm1)
# 7.設定紀錄檔等級
logger.setLevel(10)  # debug
# 8.記錄紀錄檔
logger.debug('寫了半天 好累啊 好熱啊')
import logging
import logging.config
# 定義紀錄檔輸出格式 開始
standard_format = '[%(asctime)s][%(threadName)s:%(thread)d][task_id:%(name)s][%(filename)s:%(lineno)d]' \
                  '[%(levelname)s][%(message)s]'  # 其中name為getlogger指定的名字
simple_format = '[%(levelname)s][%(asctime)s][%(filename)s:%(lineno)d]%(message)s'
# 自定義檔案路徑
logfile_path = 'a3.log'
LOGGING_DIC = {
    'version': 1,
    'disable_existing_loggers': False,
    'formatters': {
        'standard': {
            'format': standard_format
        },
        'simple': {
            'format': simple_format
        },
    },
    'filters': {},  # 過濾紀錄檔
    'handlers': {
        # 列印到終端的紀錄檔
        'console': {
            'level': 'DEBUG',
            'class': 'logging.StreamHandler',  # 列印到螢幕
            'formatter': 'simple'
        },
        # 列印到檔案的紀錄檔,收集info及以上的紀錄檔
        'default': {
            'level': 'DEBUG',
            'class': 'logging.handlers.RotatingFileHandler',  # 儲存到檔案
            'formatter': 'standard',
            'filename': logfile_path,  # 紀錄檔檔案
            'maxBytes': 1024 * 1024 * 5,  # 紀錄檔大小 5M
            'backupCount': 5,
            'encoding': 'utf-8',  # 紀錄檔檔案的編碼,再也不用擔心中文log亂碼了
        },
    },
    'loggers': {
        # logging.getLogger(__name__)拿到的logger設定
        '': {
            'handlers': ['default', 'console'],  # 這裡把上面定義的兩個handler都加上,即log資料既寫入檔案又列印到螢幕
            'level': 'DEBUG',
            'propagate': True,  # 向上(更高level的logger)傳遞
        },  # 當鍵不存在的情況下 (key設為空字串)預設都會使用該k:v設定
        # '購物車記錄': {
        #     'handlers': ['default','console'],  # 這裡把上面定義的兩個handler都加上,即log資料既寫入檔案又列印到螢幕
        #     'level': 'WARNING',
        #     'propagate': True,  # 向上(更高level的logger)傳遞
        # },  # 當鍵不存在的情況下 (key設為空字串)預設都會使用該k:v設定
    },
}
logging.config.dictConfig(LOGGING_DIC)  # 自動載入字典中的設定
# logger1 = logging.getLogger('購物車記錄')
# logger1.warning('尊敬的VIP客戶 晚上好 您又來啦')
# logger1 = logging.getLogger('註冊記錄')
# logger1.debug('jason註冊成功')
logger1 = logging.getLogger('紅浪漫顧客消費記錄')
logger1.debug('慢男 猛男 騷男')

11.re模組 關於正則相關的模組

import re
re.findall(正規表示式,待匹配的內容)  
re.finditer(正規表示式,待匹配的內容)
re.search(正規表示式,待匹配的內容)
re.match(正規表示式,待匹配的內容)
obj = re.compile(正規表示式)

re.split()  # 切割
re.sub()  # 替換
re.subn()  # 替換

分組優先展示
findall()  # 預設分組優先
findall((?:\d))  # 取消分組優先

分組起別名
(?P<user_id>\d)
res = re.search()
res.group(0)
res.group('user_id')

關於正規表示式 是一門獨立的語言

中括號括起來 裡面填寫一些內容
[0123456789]
[0-9]
[a-z]
[A-Z]
[0-9A-Za-z]
"""
字元組預設情況下篩選資料是挨個挨個匹配 字元組內所有的內容預設都是或關係
"""
.			匹配除換行符意外的任意字元
\w			匹配數位、字母、下劃線
\W			匹配除數位、字母、下劃線
\d			匹配數位
^			匹配字串的開頭
$			匹配字串的結尾
()			正規表示式分組
[^]			中括號內取反操作查詢其他
a|b			匹配a或者b
"""特殊符號預設情況下篩選資料也是挨個挨個匹配"""
*			零次或多次
+			一次或多次
?			零次或一次
{n}			 n次
{n,}		 n次或多次
{n,m}		 n到m次
"""量詞預設情況下都是貪婪匹配>>>:儘可能多的匹"""
量詞後面如果跟了問號則會變為非貪婪匹配
.*
.*?
"""
使用貪婪匹配或者非貪婪匹配 建議在前後加上明確的結束標誌
"""

12.requests網路爬蟲模組 能夠模擬瀏覽器傳送網路請求

'''爬取部落格園檔案'''
import re

import requests

blog_a_list = []
for i in range(1, 3):
    url_text = requests.get(f"https://www.cnblogs.com/almira998/default.html?page={i}").text
    # https: // www.cnblogs.com / Leethon - lizhilog /
    # https://www.cnblogs.com/almira998/
    # print(url_text)
    blog_url = re.findall('<a class="postTitle2 vertical-middle" href="(.*?)">', url_text)
    for url in blog_url:
        res = requests.get(url).text
        blog_title = re.findall('<title>(.*?) - 阿麗米熱 - 部落格園</title>', res)
        # with open(f'{blog_title}.txt', 'w',encoding='utf8')as f:
        #     for line in res:
        #         f.write(line)
        blog_a_list.append(f'- [{blog_title[0]}]({url})')

blog_a_list.reverse()
for blog_a in blog_a_list:
    print(blog_a)

'''爬取鏈家二手房資料'''
import requests
import re

res = requests.get('https://sh.lianjia.com/ershoufang/pudong/')
# print(res.text)
data = res.text

home_title_list = re.findall(
    '<a class="" href=".*?" target="_blank" data-log_index=".*?"  data-el="ershoufang" data-housecode=".*?" data-is_focus="" data-sl="">(.*?)</a>',
    data)
# print(home_title_list)
home_name_list = re.findall('<a href=".*?" target="_blank" data-log_index=".*?" data-el="region">(.*?) </a>', data)
# print(home_name_list)
home_street_list = re.findall(
    '<div class="positionInfo"><span class="positionIcon"></span><a href=".*?" target="_blank" data-log_index=".*?" data-el="region">.*? </a>   -  <a href=".*?" target="_blank">(.*?)</a> </div>',
    data)
# print(home_street_list)
home_info_list = re.findall('<div class="houseInfo"><span class="houseIcon"></span>(.*?)</div>', data)
# print(home_info_list)
home_watch_list = re.findall('<div class="followInfo"><span class="starIcon"></span>(.*?)</div>', data)
# print(home_watch_list)
home_total_price_list = re.findall(
    '<div class="totalPrice totalPrice2"><i> </i><span class="">(.*?)</span><i>萬</i></div>', data)
# print(home_total_price_list)
home_unit_price_list = re.findall(
    '<div class="unitPrice" data-hid=".*?" data-rid=".*?" data-price=".*?"><span>(.*?)</span></div>', data)
# print(home_unit_price_list)
home_data = zip(home_title_list, home_name_list, home_street_list, home_info_list, home_watch_list,
                home_total_price_list, home_unit_price_list)
with open(r'home_data.txt','w',encoding='utf8') as f:
    for data in home_data:
        print(
            """
            房屋標題:%s
            小區名稱:%s
            街道名稱:%s
            詳細資訊:%s
            關注程度:%s
            房屋總價:%s
            房屋單價:%s
            """%data
        )
        f.write("""
                房屋標題:%s
                小區名稱:%s
                街道名稱:%s
                詳細資訊:%s
                關注程度:%s
                房屋總價:%s
                房屋單價:%s\n
                """%data)

三、Python第三方模組

第三方模組:別人寫的模組 一般情況下功能都特別強大
    
我們如果想使用第三方模組 第一次必須先下載後面才可以反覆使用(等同於內建模組)

下載第三方模組的方式
	1.pip工具
    	注意每個直譯器都有pip工具 如果我們的電腦上有多個版本的直譯器那麼我們在使用pip的時候一定要注意到底用的是哪一個 否則極其任意出現使用的是A版本直譯器然後用B版本的pip下載模組
       為了避免pip衝突 我們在使用的時候可以新增對應的版本號
    	   python27			 pip2.7
     	  python36			pip3.6
         python38			pip3.8
  		下載第三方模組的句式
        	pip install 模組名
       下載第三方模組臨時切換倉庫
    		 pip install 模組名 -i 倉庫地址
       下載第三方模組指定版本(不指定預設是最新版)
    		 pip install 模組名==版本號 -i 倉庫地址
 	2.pycharm提供快捷方式
    	群內截圖
      	
"""
下載第三方模組可能會出現的問題
	1.報錯並有警告資訊
		WARNING: You are using pip version 20.2.1;
		原因在於pip版本過低 只需要拷貝後面的命令執行更新操作即可
		d:\python38\python.exe -m pip install --upgrade pip
		更新完成後再次執行下載第三方模組的命令即可
	2.報錯並含有Timeout關鍵字
		說明當前計算機網路不穩定 只需要換網或者重新執行幾次即可
	3.報錯並沒有關鍵字
		面向百度搜尋
			pip下載XXX報錯:拷貝錯誤資訊
		通常都是需要使用者提前準備好一些環境才可以順利下載
	4.下載速度很慢
		pip預設下載的倉庫地址是國外的 python.org
		我們可以切換下載的地址
		pip install 模組名 -i 倉庫地址
		pip的倉庫地址有很多 百度查詢即可
		清華大學 :https://pypi.tuna.tsinghua.edu.cn/simple/
		阿里雲:http://mirrors.aliyun.com/pypi/simple/
		中國科學技術大學 :http://pypi.mirrors.ustc.edu.cn/simple/
		華中科技大學:http://pypi.hustunique.com/
		豆瓣源:http://pypi.douban.com/simple/
		騰訊源:http://mirrors.cloud.tencent.com/pypi/simple
		華為映象源:https://repo.huaweicloud.com/repository/pypi/simple/
"""

四、關於軟體開發目錄

檔案以及目錄的名字可以變換 不是已經固定死了的 但是思想是不變的>>>:分類管理
目錄規範主要規定開發程式的過程中針對不同的檔案功能需要做不同的分類、以下舉例

  1. bin資料夾 start.py 啟動檔案
  2. conf資料夾 settings.py 組態檔
  3. core資料夾 src.py 核心檔案
  4. interface資料夾 login.py 介面檔案
  5. db資料夾 db_handler.py 資料庫的
  6. log資料夾 log.log 紀錄檔檔案
  7. lib資料夾 common.py 公共功能
  8. readme檔案 txt檔案 相關說明
  9. requirements.txt 不能寫錯 模組版本