包,logging日誌模塊,copy深淺拷貝

一 包 package

包就是一個包含了 __init__.py文件的文件夾

包是模塊的一種表現形式,包即模塊

首次導入包:

  先創建一個執行文件的名稱空間

    1.創建包下面的__init__.py文件的名稱空間

    2.運行包下面的__init__,py文件中的代碼,將產生的名字放入放入包下面的__init__.py文件的名稱空間

    3.在執行文件中拿到一個指向包下面的__init__.py文件名稱空間

執行文件在 '  import 包名 ' 的時候拿到的是包下面 __init__.py 文件的名稱空間的內容

在導入語句中,點號的左邊都是文件夾

 

 相對導入:

  包下的py文件都是用來被導入的模塊,所以可以在__init__.py裏可以使用相對路徑

絕對導入:

   缺點:當包的名字改動時,所有的導入語句都需要改動

 

 

 

當你作爲包的設計者來說
    1.當模塊的功能特別多的情況下 應該分文件管理
    2.每個模塊之間爲了避免後期模塊改名的問題 你可以使用相對導入(包裏面的文件都應該是被導入的模塊)

站在包的開發者 如果使用絕對路徑來管理的自己的模塊 那麼它只需要永遠以包的路徑爲基準依次導入模塊
站在包的使用者 你必須得將包所在的那個文件夾路徑添加到system path中(******)

python2如果要導入包 包下面必須要有__init__.py文件
python3如果要導入包 包下面沒有__init__.py文件也不會報錯
當你在刪程序不必要的文件的時候 千萬不要隨意刪除__init__.py文件

 二.logging日誌模塊

  日誌分五個等級  默認打印到終端

logging.debug('調試日誌debug') # 10
logging.info('消息info')  # 20
logging.warning('警告warn')  # 30
logging.error('錯誤error')  # 40
logging.critical('嚴重critical')  # 5

 

 

filename='日誌文件的名字'
formatter='日誌信息的格式'
datefmt='日誌時間的格式'
leve=10 # 日誌級別 比10大的都執行,一般默認30
stream 是否打印到終端
ps : 
    1.日誌文件默認以 a 模式寫入
logging.basicConfig(filename='access.log',
                    format='%(asctime)s - %(name)s - %(levelname)s -%(module)s:  %(message)s',
                    datefmt='%Y-%m-%d %H:%M:%S %p',
                    level=10,
                    # stream=True
                    )

 

'''日誌使用流程步驟'''
1.logger 對象:負責生產日誌
logger = logging.getLogger('日誌名字')
2.filter 對象:過濾日誌(瞭解)
3.handler 對象:控制日誌輸入出的位置(文件/終端)
hd1 = logging.FileHandler('文件名字',encoding='utf-8') # 輸出到文件中
hd2 = 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 - %(levelname)s -%(module)s:  %(message)s',
            datefmt='%Y-%m-%d'
5.給logging對象綁定handler對象
logger.addHandler(hd1)
logger.addHandler(hd2)
6.給handler綁定formatter對象
hd1.setFormatter(fm1)
hd1.setFormatter(fm2) 
7.設置日誌等級
logger.setLevel(10)
8.記錄日誌
logger.debug('logging日誌模塊')

 

log配置字典(模板)

import os
import logging

# 格式 standard :  standard_format
standard_format = '[%(asctime)s][%(threadName)s:%(thread)d][task_id:%(name)s][%(filename)s:%(lineno)d]' \
                  '[%(levelname)s][%(message)s]' #其中name爲getlogger指定的名字
# 格式 simple : simple_format
simple_format = '[%(levelname)s][%(asctime)s][%(filename)s:%(lineno)d]%(message)s'


# 定義日誌輸出格式 結束
"""
下面的兩個變量對應的值 需要你手動修改
"""
logfile_dir = os.path.dirname(__file__)  # log文件的目錄
logfile_name = 'a3.log'  # log文件名

# 如果不存在定義的日誌目錄就創建一個
if not os.path.isdir(logfile_dir):
    os.mkdir(logfile_dir)

# log文件的全路徑
logfile_path = os.path.join(logfile_dir, logfile_name)

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)傳遞
        },  # 當鍵不存在的情況下 默認都會使用該k:v配置
    },
}

View Code

 

 

三.hashlib加密模塊

應用場景:

  1.密碼的密文存儲

  2.校驗文件內容是否一致  

密文算法越複雜,生成的密文越長
消耗的時間越長,佔空間越大
通常用md5 就夠了
明文轉密文的順序
md = hashlib.md5()  # 生成一個造密文的對象,算法是md5
# md.update('hello'.encode('utf-8'))  # 往對象裏傳明文數據 update 只能接受 bytes 類型的數據
md.update(b'hello')  # 往對象裏傳明文數據 update 只能接受 bytes 類型的數據
print(md.hexdigest())  # 獲取明文數據對應的密文
傳入的內容 可以分多次傳入 只要傳入的內容相同 那麼生成的密文肯定相同
md = hashlib.md5()
md.update(b'areyouok?')
md.update(b'are')
md.update(b'you')
md.update(b'ok?')
print(md.hexdigest())  # 408ac8c66b1e988ee8e2862edea06cc7
# 408ac8c66b1e988ee8e286
加鹽處理
import hashlib

def get_md5(data):
    md = hashlib.md5()
    md.update('加鹽'.encode('utf-8'))
    md.update(data.encode('utf-8'))
    return md.hexdigest()


password = input('password>>>:')
res = get_md5(password)
print(res)

 

 

四.copy深拷貝淺拷貝模塊

import copy

l = [1,2,[1,2]]
# l1 = l
# print(id(l),id(l1))

#  淺拷貝
l1 = copy.copy(l)  # 拷貝一份 .......  淺拷貝
print(id(l),id(l1))  # 相同
l[0] = 222
print(l)  # [222, 2, [1, 2]]
print(l1)  # [1, 2, [1, 2]]
l[2].append(666)
print(l)  # [1, 2, [1, 2, 666]]
print(l1)  # [1, 2, [1, 2, 666]]


# 深拷貝
l1 = copy.deepcopy(l)
print(id(l),id(l1))  # 不同
l[2].append(666)
print(l)  # [1, 2, [1, 2, 666]]
print(l1)  # [1, 2, [1, 2]]


淺拷貝 :

增加了一個指針指向一個存在的內存地址

兩種方式:

  • 單層:
lst1 = ["太白","日天","哪吒","銀角大王","金角大王"]
lst2 = lst1
lst1.append("女神")
print(lst1,id(lst1))   # ['太白', '日天', '哪吒', '銀角大王', '金角大王', '女神']
2420170040264
print(lst2,id(lst2))    #['太白', '日天', '哪吒', '銀角大王', '金角大王', '女神']
2420170040264
#指向同一個內存地址,所以二者相同
lst1 = ["太白","日天","哪吒","銀角大王","金角大王"]
lst2 = lst1.copy()    # 會創建新對象, 創建對象的速度會很快. lst2 = lst1[:] 創建了新列表
lst1.append("女神")
print(lst1,id(lst1))   
#['太白', '日天', '哪吒', '銀角大王', '金角大王', '女神']
2606709613704
print(lst2,id(lst2))   
#['太白', '日天', '哪吒', '銀角大王', '金角大王'] 
2606709613832
  • 多層
lst1 = ["太白","日天",["蓋澆飯", "鍋包肉", "吱吱冒油的豬蹄子"],"哪吒","銀角大王","金角大王"]
lst2 = lst1.copy() # 會創建新對象, 創建對象的速度會很快.
lst1[2].append("油潑扯麪")
print(lst1,id(lst1),  id(lst1[2]))
# ['太白', '日天', ['蓋澆飯', '鍋包肉', '吱吱冒油的豬蹄子', '油潑扯麪'], '哪吒', '銀角大王', '金角大王'] 2923729634696 2923729612424
print(lst2,id(lst2),  id(lst2[2]))
# ['太白', '日天', ['蓋澆飯', '鍋包肉', '吱吱冒油的豬蹄子', '油潑扯麪'], '哪吒', '銀角大王', '金角大王'] 2923729636040 2923729612424

淺拷貝. 只會拷貝第⼀層. 第二層的內容不會拷貝. 所以被稱爲淺拷貝

深拷貝

增加一個指針並且開闢了新的內存,這個增加的指針指向這個新的內存

兩種方式:

  • 單層
import copy
li1 = [1, 2, 3]
li2 = copy.deepcopy(li1)
li1.append(4)
print(li1, id(li1))   # [1, 2, 3, 4]   3112618579592
print(li2, id(li2))   # [1, 2, 3]      3112618579784
  • 多層
import copy
li1 = [1, 2, 3,[4,5],6]
li2 = copy.deepcopy(li1)
li1[3].append(7)
print(li1, id(li1))    # [1, 2, 3, [4, 5, 7], 6]  2575562397512
print(li2, id(li2))    # [1, 2, 3, [4, 5], 6]    2575562398792

注:深拷貝. 把元素內部的元素完全進行拷貝複製.,不會產生一個改變另一個跟着改變的問題

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章