Python基礎之模組
一、關於模組的基礎知識
# 用來相對匯入
import
# 用來絕對匯入
from ··· import···
# 用來判斷是否執行檔案
if __name__ == '__main__':
print('哈哈哈 我是執行檔案 我可以執行這裡的子程式碼')
二、Python常見內建模組
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.佇列與堆疊
佇列:先進先出
堆疊:先進後出
# 佇列和堆疊都是一邊只能出一邊進
時間的三種表現形式
time.time() # 時間戳 1674137513.8003848
time.strftime('%Y-%m-%d %H:%M:%S %X') # %H:%M:%S與%X意思一樣都可以獲取時分秒
time.localtime() # 以結構化時間的格式列印當地時間
time.sleep(10) # 讓程式原地休息10秒
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 時間差值
random.random() # 隨機產生0到1之間的小數
random.randint(1, 6) # 隨機產生1到6之間的整數
random.randrange() # 隨機產生範圍
random.choice() # 隨機抽取一個 抽獎的 '一等獎'
random.choices() # 隨機抽取一個 抽獎的 ['一等獎']
random.sample() # 可以指定一次抽取幾個樣本
random.shuffle() # 類似於洗牌 給出一個列表 每次都會隨機打亂列表裡面資料值的順序
# 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'))
sys.path # 獲取執行檔案的sys.path路徑
sys.getrecursionlimit() # 獲取Python直譯器預設最大遞迴深度
sys.setrecursionlimit(2000) #修改Python預設最大遞迴深度
sys.version # 獲取當前直譯器的版本資訊
sys.platform # 可以獲取平臺資訊 win32
# 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)
# 何為加密
將明文資料處理成密文資料 讓人無法看懂
加密演演算法不變 內容如果相同 那麼結果肯定相同
# 為什麼加密
保證資料的安全
# 如何判斷資料是否是加密的
一串沒有規律的字串(數位、字母、符號)
加密之後的結果是無法反解密的
# 密文的長短有何講究
密文越長表示使用的加密演演算法(資料的處理過程)越複雜
# 常見的加密演演算法有哪些
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
import subprocess
res = subprocess.Popen(
'asdas', # 作業系統要執行的命令
shell=True, # 固定設定
stdin=subprocess.PIPE, # 輸入命令
stdout=subprocess.PIPE, # 輸出結果
)
print('正確結果', res.stdout.read().decode('gbk')) # 獲取作業系統執行命令之後的正確結果
print('錯誤結果', res.stderr) # 獲取作業系統執行命令之後的錯誤結
# 紀錄檔的組成
產生紀錄檔
過濾紀錄檔
輸出紀錄檔
紀錄檔格式
# 如何理解紀錄檔
紀錄檔就是記錄行為舉止的操作
# 紀錄檔的級別
有五種級別 程式碼不需要掌握 會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('慢男 猛男 騷男')
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次
"""量詞預設情況下都是貪婪匹配>>>:儘可能多的匹"""
量詞後面如果跟了問號則會變為非貪婪匹配
.*
.*?
"""
使用貪婪匹配或者非貪婪匹配 建議在前後加上明確的結束標誌
"""
'''爬取部落格園檔案'''
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/
"""
四、關於軟體開發目錄
檔案以及目錄的名字可以變換 不是已經固定死了的 但是思想是不變的>>>:分類管理
目錄規範主要規定開發程式的過程中針對不同的檔案功能需要做不同的分類、以下舉例