Python入門から実践まで:python共通モジュール

目次

1.時間モジュール

1.タイムスタンプ

2.フォーマット時間

3.構造化された時間

4. 一般的な使い方: プログラムの実行時間を計算する

二、日時モジュール

三、ランダムモジュール

四、OS モジュール

1. os モジュールは、プログラムとオペレーティング システム間の対話を担当します。

2. OS の主要モジュール:

3. OS 共通操作: 現在のパスの絶対パスを取得する、現在のパスの親パスを取得する、親パスなどを取得する

五、sysモジュール

1. sys モジュールは、プログラムと Python インタープリター間の対話を担当します。

2.sys キー モジュール

3.小さなケース:プログレスバーの印刷を実現

Six、json、pickle モジュール

1.連載

2. シリアル化の利点:

3.json形式

セブン、ピクルス形式

1.ピクルスの紹介

2. 漬け込み作業

八、hashlibモジュール

1. hashlib の紹介

2. ハッシュ値の特徴:

3. ハッシュの基本操作 (例として md5 を取り上げます)

4. クラッシュ ライブラリ クラック ハッシュ アルゴリズムの暗号化

9、shutil モジュール

1. shutil の紹介

2. ファイルをコピーする

3. ファイルを移動する

4. 圧縮ファイルの読み取りとアーカイブ

5.ファイルを解凍します

10、サブプロセス モジュール

1. subsprocess モジュールの紹介

2.サブプロセスの基本操作

Eleven、xml、および shelve モジュール

1. shelve モジュールの紹介

2. シェルフモジュールの基本操作

3.xml モジュール

1. xml モジュールの紹介

4.xmlモジュールの基本操作

5.自分でxml文書を作成できる

12. configparser モジュール

1. configparser モジュールの基本操作

十三、ロギングモジュール

1. ログレベル

2. デフォルト レベルは警告で、デフォルトで端末に出力されます。

3. ロギング モジュールのグローバル構成を指定し、すべてのロガーに有効で、ファイルへの出力を制御します。

4. logging モジュールの Formatter、Handler、Logger、Filter オブジェクト

5、ロガーとハンドラーのレベル

6. 申請

1. アプリケーション 1

  2. アプリケーション 2: シンプルなケース

14、再モジュール

1. 正規表現の紹介

2.よく使われるマッチングモード     

                             

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             


1.時間モジュール

1.タイムスタンプ

time_stamp = time.time()
print(time_stamp, type(time_stamp))

2.フォーマット時間

format_time = time.strftime("%Y-%m-%d %X")
print(format_time, type(format_time))

2022-08-31 <class 'str'>

3.構造化された時間

print('本地时区的struct_time:\n{}'.format(time.localtime()))
print('UTC时区的struct_time:\n{}'.format(time.gmtime()))



本地时区的struct_time:
time.struct_time(tm_year=2022, tm_mon=8, tm_mday=31, tm_hour=16, tm_min=14, tm_sec=41, tm_wday=2, tm_yday=243, tm_isdst=0)
UTC时区的struct_time:
time.struct_time(tm_year=2022, tm_mon=8, tm_mday=31, tm_hour=8, tm_min=14, tm_sec=41, tm_wday=2, tm_yday=243, tm_isdst=0)

4. 一般的な使い方: プログラムの実行時間を計算する

# 推迟指定的时间运行,单位为秒
start = time.time()
time.sleep(3)
end = time.time()
 
print(end-start)

二、日時モジュール

このモジュールは、時間の加算および減算モジュールと見なすことができます

# 返回当前时间
print(datetime.datetime.now())

# 当前时间+3天
print(datetime.datetime.now() + datetime.timedelta(3))
# 当前时间-3天
print(datetime.datetime.now() + datetime.timedelta(-3))
# 当前时间+30分钟
print(datetime.datetime.now() + datetime.timedelta(minutes=30))
# 时间替换
c_time = datetime.datetime.now()
print(c_time.replace(minute=20, hour=5, second=13))

print(datetime.date.fromtimestamp(time.time()))  #换算成年月日
2019-03-07

三、ランダムモジュール

# 大于0且小于1之间的小数
print(random.random())
# 大于等于1且小于等于3之间的整数
print(random.randint(1, 3))
# 大于1小于3的小数,如1.927109612082716
print(random.uniform(1, 3))
# 列表内的任意一个元素,即1或者‘23’或者[4,5]
print(random.choice([1, '23', [4, 5]]))
1

------------smaple-------比较常用在数据导入的时候像随机选择数据
# random.sample([], n),列表元素任意n个元素的组合,示例n=2
print(random.sample([1, '23', [4, 5]], 2))
[[4, 5], '23']

lis = [1, 3, 5, 7, 9]
# 打乱l的顺序,相当于"洗牌"
random.shuffle(lis)
print(lis)
[1, 3, 9, 7, 5]

四、OS モジュール

1. os モジュールは、プログラムとオペレーティング システム間の対話を担当します。

2. OS の主要モジュール:

os.getcwd()

os.path.abspath('D:\python_base')\

os.path.split('C:\\WINDOWS\\system32\\cmd.exe')

os.path.join('C:\\WINDOWS\\system32\\cmd.exe','こんにちは')

os.path.getsize('C:\\WINDOWS\\system32\\cmd.exe')

3. OS 共通操作: 現在のパスの絶対パスを取得する、現在のパスの親パスを取得する、親パスなどを取得する

# -*- coding: utf-8 -*-

'''
@Time    : 2022/09/01 10:25
@Author  : Rice
@CSDN : C_小米同学
@FileName: test.py
'''
import os
print(os.path.abspath(__file__)) #返回当前文件的绝对路劲(路径+文件名)
print(os.path.dirname(os.path.abspath(__file__))) #返回当前文件的父路径
print(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))#返回当前文件的父路径的父路径
print(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))))

五、sysモジュール

1. sys モジュールは、プログラムと Python インタープリター間の対話を担当します。

2.sys キー モジュール

sys.path: PYTHONPATH 環境変数の値で初期化された、モジュールの検索パスを返します。

sys.version: Python インタープリターのバージョン情報を取得します

sys.exit(n): プログラムを終了、正常終了時は exit(0)

3.小さなケース:プログレスバーの印刷を実現

#=========知识储备==========
#进度条的效果
[#             ]
[##            ]
[###           ]
[####          ]

#指定宽度
print('[%-15s]' %'#')
print('[%-15s]' %'##')
print('[%-15s]' %'###')
print('[%-15s]' %'####')

#打印%
print('%s%%' %(100)) #第二个%号代表取消第一个%的特殊意义

#可传参来控制宽度
print('[%%-%ds]' %50) #[%-50s]
print(('[%%-%ds]' %50) %'#')
print(('[%%-%ds]' %50) %'##')
print(('[%%-%ds]' %50) %'###')


#=========实现打印进度条函数==========
import sys
import time

def progress(percent,width=50):
    if percent >= 1:
        percent=1
    show_str=('[%%-%ds]' %width) %(int(width*percent)*'#')
    print('\r%s %d%%' %(show_str,int(100*percent)),file=sys.stdout,flush=True,end='')


#=========应用==========
data_size=1025
recv_size=0
while recv_size < data_size:
    time.sleep(0.1) #模拟数据的传输延迟
    recv_size+=1024 #每次收1024

    percent=recv_size/data_size #接收的比例
    progress(percent,width=70) #进度条的宽度70

Six、json、pickle モジュール

1.連載

オブジェクト (変数) をメモリからストレージまたは転送に変更するプロセスはシリアライゼーションと呼ばれ、Python ではピクルと呼ばれ、他の言語ではシリアライゼーション、マーシャリング、フラット化とも呼ばれます。

2. シリアル化の利点:

1.永続的に状態を保存: メモリはデータを永続的に保存することはできません. プログラムが一定期間実行されている場合, プログラムの電源を切るか再起動すると, 一定期間メモリ内のプログラムに関するデータ (構造を含む)前にクリアされます。ただし、電源をオフにするか、プログラムを再起動する前に、プログラムの現在のメモリ内のすべてのデータが保存 (ファイルに保存) されるため、次のプログラムの実行で前のデータをファイルからロードして続行できます。これがシリアル化です。

2.クロスプラットフォームのデータ相互作用: シリアル化する場合、シリアル化されたコンテンツをディスクに書き込むだけでなく、ネットワークを介して他のマシンに送信することもできます. 送信側と受信側がシリアル化された形式を使用することに同意した場合、それはプラットフォーム/言語の差別化によってもたらされる限界を克服し、クロスプラットフォームのデータ相互作用を実現します。

3.json形式

Jsonシリアライズはpython固有のものではなく、javaなどの言語にもjsonシリアライズが関わっているため、jsonシリアライズを利用することでクロスプラットフォームのデータ転送という目的を達成することができます。isonデータ型とpythonデータ型の対応表

セブン、ピクルス形式

1.ピクルスの紹介

Pickle シリアライゼーションは、他のすべてのプログラミング言語固有のシリアライゼーションの問題と同様に、Python にしか使用できず、異なるバージョンの Python は相互に互換性がない可能性があります. したがって、重要でないデータのみを Pickle で保存できます。デシリアライゼーションも問題ありません。ただし、pickle の利点は、オブジェクトを含むすべてのデータ型を Python に格納できることですが、json には格納できませんpickle モジュールのシリアライゼーションとデシリアライゼーションのプロセスを下の図に示します。

2. 漬け込み作業

八、hashlibモジュール

1. hashlib の紹介

ハッシュはアルゴリズムです (Python3. バージョンでは、hashlib モジュールが md5 モジュールと sha モジュールの代わりに使用され、主に SHA1、SHA224、SHA256、SHA384、SHA512、MD5 アルゴリズムを提供します)。このアルゴリズムは着信コンテンツを受け入れ、文字列を取得します。計算後のハッシュの値。

2. ハッシュ値の特徴:

1. 入力内容が同じであれば得られるハッシュ値は同じであり、非平文パスワード送信時のパスワード検証に利用できる

2. ハッシュ値をコンテンツに戻すことができない、つまり、非平文パスワードのセキュリティを保証できる

3. 使用するハッシュアルゴリズムが変わらない限り、検証内容がどんなに大きくても、得られるハッシュ値の長さは一定であり、テキストのハッシュ処理に使用できます.ハッシュアルゴリズムは実際にはファクトリと見なすことができます.下図のように、あなたが送った原材料を工場が受け取り、加工して戻ってきたものがハッシュ値です。

3. ハッシュの基本操作 (例として md5 を取り上げます)

4. クラッシュ ライブラリ クラック ハッシュ アルゴリズムの暗号化

ハッシュ暗号化アルゴリズムは非常に強力に見えますが、特定の欠点があります。つまり、次のコードに示すように、資格証明によって元に戻すことができます。

9、shutil モジュール

1. shutil の紹介

osモジュールと比較して、shutilモジュールはファイルとディレクトリの高度な処理に使用され、ファイルの割り当て、移動、削除、圧縮、解凍のサポートなどの機能を提供します。 

2. ファイルをコピーする

shutil モジュールの主な機能はファイルをコピーすることであり、7 つの実装方法があります。


    1. shutil.copyfileobj(file1, file2)は、file1 の内容を上書きしてコピーし、file2 を上書きします。file1 と file2 は、開いているファイル オブジェクトを表します。

2. shutil.copyfile(file1, file2) 上書きコピー
    も上書きですが、ファイルを開く必要はなく、ファイル名を直接上書きします(ソースコードはcopyfileobjのまま)。

3. shutil.copymode(file1,file2) パーミッションのコピーは
    、ファイルのパーミッションのみをコピーし、ファイルの内容、グループ、およびユーザーを変更せず、オブジェクトを返しません。

4. shutil.copystart (file1, file2) status は、
    コピーされたファイルのすべてのステータス情報をコピーします。これには、権限、グループ、ユーザー、時間などが含まれます。オブジェクトは返されません。


    5. shutil.copy(file1, file2) content and permissionは、コピーされたファイルの内容と許可をコピーします。これは、copyfile を最初に実行してから copysmode を実行することと同じです。


    6. shutil.copy2(file1, file2) content and permissionsは、コピーされたファイルのコンテンツとすべてのステータス情報をコピーします。これは、最初に copyfile を実行してから copystart を実行することと同じです。

7. shutil.copytree() 再帰的コピー
    ファイルの内容とステータス情報を再帰的にコピーします

3. ファイルを移動する

関数shutil.move()function を使用して、ファイルを再帰的に移動または名前変更し、ターゲットを返します. ターゲットが既存のディレクトリの場合、src は現在のディレクトリに移動されます. ターゲットが既に存在し、ディレクトリでない場合は、上書きされる可能性があります.

4. 圧縮ファイルの読み取りとアーカイブ

関数 shutil.make_archive() を使用してアーカイブを作成し、アーカイブされた名前を返します。
構文は次のとおりです。
shutil.make_archive(base_name,format[,root_dir[,base_dir[,verbose[,dry_run[,owner[,group[,logger]]]]]])

1.base_name は、パスを含む、作成するファイルの名前です。
2.format は、圧縮形式、オプションの zip、tar または bztar などを示します。
3.root_dir は、アーカイブのディレクトリです。

5.ファイルを解凍します

関数を使用してshutil.unpack_archive(filename[,extract_dir[,format]])アンパッキングを分析します。

1.filename は、アーカイブのフル パスです。

2.extract_dir は、解凍されたアーカイブのターゲット ディレクトリ名です。

3.format は、解凍されたファイルの形式です

10、サブプロセス モジュール

1. subsprocess モジュールの紹介

Subprocess は python の組み込みモジュールで、このモジュール内の Popen は、ユーザーが入力したコマンドラインが存在するかどうかを確認できます。

1. 存在する場合は、コンテンツを stdout パイプラインに書き込みます

2. 存在しない場合は、情報を stderr パイプに書き込みます。

なお、このモジュールの返ってきた結果は、開発者が一度しか見ることができないので、複数回見たい場合は、最初の出力時にすべての情報を変数に書き込む必要があります。

2.サブプロセスの基本操作

Popen の基本形式: subprocess.Popen('command', shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)

shell=True は、ターミナルで実行するコマンドを意味します

stdout=sbuprocess.PIPE は、コマンドが存在する場合、結果を stdout パイプに書き込むことを意味します。

stderr=sbuprocess.PIPE は、コマンドが存在しない場合、結果が stderr パイプに吸い込まれることを意味します

import subprocess

r = subprocess.Popen('wget -q -o xxx', shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)

print(r.stdout.read().decode('utf8'))
print(r.stderr.read().decode('utf8'))

Eleven、xml、および shelve モジュール

1. shelve モジュールの紹介

Shelve は、Python のメモリ オブジェクトを保存するために便利に使用できるキー値データベースに似ており、pickle を使用して内部的にデータをシリアル化します。

簡単に言えば、ユーザーはリスト、辞書、またはユーザー定義のクラス インスタンスをシェルフに保存し、次に必要になったときに直接取り出すことができます。

これは Python のメモリ オブジェクトであり、従来のデータベースのように最初にデータを取り出し、そのデータを使用して必要なオブジェクトを再構築する必要はありません。

2. シェルフモジュールの基本操作


import shelve
import datetime

d = shelve.open('test1')  # 打开一个文件
info = {
    "age":23,
    "color":"red"
}

name = ["tom", "bob", "lili"]

d["name"] = name  # 持久化列表
d["info"] = info  # 持久化字典
d["data"] = datetime.datetime.now()

d.close()
d = shelve.open('test1')  # 打开一个文件
print(d.get("name"))
print(d.get("info"))
print(d.get("data"))

3.xml モジュール

1. xml モジュールの紹介

xml プロトコルはさまざまな言語でサポートされています. python では、次のモジュールを使用して xml を操作できます。

4.xmlモジュールの基本操作

例を挙げましょう: 最初に新しい xml ファイル (xmltest.xml という名前) を作成します。内容は次のとおりです。

<?xml version="1.0"?>
<data>
    <country name="Liechtenstein">
        <rank updated="yes">2</rank>
        <year>2008</year>
        <gdppc>141100</gdppc>
        <neighbor name="Austria" direction="E"/>
        <neighbor name="Switzerland" direction="W"/>
    </country>
    <country name="Singapore">
        <rank updated="yes">5</rank>
        <year>2011</year>
        <gdppc>59900</gdppc>
        <neighbor name="Malaysia" direction="N"/>
    </country>
    <country name="Panama">
        <rank updated="yes">69</rank>
        <year>2011</year>
        <gdppc>13600</gdppc>
        <neighbor name="Costa Rica" direction="W"/>
        <neighbor name="Colombia" direction="E"/>
    </country>
</data>

最も基本的な 3 つの操作を見てみましょう。



# print(root.iter('year')) #全文搜索
# print(root.find('country')) #在root的子节点找,只找一个
# print(root.findall('country')) #在root的子节点找,找所有

import xml.etree.ElementTree as ET
 
tree = ET.parse("xmltest.xml")
root = tree.getroot()
print(root.tag)
 
#遍历xml文档
for child in root:
    print('========>',child.tag,child.attrib,child.attrib['name'])
    for i in child:
        print(i.tag,i.attrib,i.text)
 
#只遍历year 节点
for node in root.iter('year'):
    print(node.tag,node.text)
#---------------------------------------

import xml.etree.ElementTree as ET
 
tree = ET.parse("xmltest.xml")
root = tree.getroot()
 
#修改
for node in root.iter('year'):
    new_year=int(node.text)+1
    node.text=str(new_year)
    node.set('updated','yes')
    node.set('version','1.0')
tree.write('test.xml')
 
 
#删除node
for country in root.findall('country'):
   rank = int(country.find('rank').text)
   if rank > 50:
     root.remove(country)
 
tree.write('output.xml')
#在country内添加(append)节点year2
import xml.etree.ElementTree as ET
tree = ET.parse("a.xml")
root=tree.getroot()
for country in root.findall('country'):
    for year in country.findall('year'):
        if int(year.text) > 2000:
            year2=ET.Element('year2')
            year2.text='新年'
            year2.attrib={'update':'yes'}
            country.append(year2) #往country节点下添加子节点

tree.write('a.xml.swap')

5.自分でxml文書を作成できる

import xml.etree.ElementTree as ET
 
 
new_xml = ET.Element("namelist")
name = ET.SubElement(new_xml,"name",attrib={"enrolled":"yes"})
age = ET.SubElement(name,"age",attrib={"checked":"no"})
sex = ET.SubElement(name,"sex")
sex.text = '33'
name2 = ET.SubElement(new_xml,"name",attrib={"enrolled":"no"})
age = ET.SubElement(name2,"age")
age.text = '19'
 
et = ET.ElementTree(new_xml) #生成文档对象
et.write("test.xml", encoding="utf-8",xml_declaration=True)
 
ET.dump(new_xml) #打印生成的格式

12. configparser モジュール

1. configparser モジュールの基本操作

最初に構成ファイルを作成します (接尾辞は.ini/.confgです)

設定ファイルは以下の通り

読み取り操作:

import configparser

config=configparser.ConfigParser()
config.read('a.cfg')

#查看所有的标题
res=config.sections() #['section1', 'section2']
print(res)

#查看标题section1下所有key=value的key
options=config.options('section1')
print(options) #['k1', 'k2', 'user', 'age', 'is_admin', 'salary']

#查看标题section1下所有key=value的(key,value)格式
item_list=config.items('section1')
print(item_list) #[('k1', 'v1'), ('k2', 'v2'), ('user', 'egon'), ('age', '18'), ('is_admin', 'true'), ('salary', '31')]

#查看标题section1下user的值=>字符串格式
val=config.get('section1','user')
print(val) #egon

#查看标题section1下age的值=>整数格式
val1=config.getint('section1','age')
print(val1) #18

#查看标题section1下is_admin的值=>布尔值格式
val2=config.getboolean('section1','is_admin')
print(val2) #True

#查看标题section1下salary的值=>浮点型格式
val3=config.getfloat('section1','salary')
print(val3) #31.0

いくつかの変更操作もあります。

import configparser

config=configparser.ConfigParser()
config.read('a.cfg',encoding='utf-8')


#删除整个标题section2
config.remove_section('section2')

#删除标题section1下的某个k1和k2
config.remove_option('section1','k1')
config.remove_option('section1','k2')

#判断是否存在某个标题
print(config.has_section('section1'))

#判断标题section1下是否有user
print(config.has_option('section1',''))


#添加一个标题
config.add_section('egon')

#在标题egon下添加name=egon,age=18的配置
config.set('egon','name','egon')
config.set('egon','age',18) #报错,必须是字符串


#最后将修改的内容写入文件,完成最终的修改
config.write(open('a.cfg','w'))

上記の方法に基づいて、ini ファイルを追加します。

import configparser
  
config = configparser.ConfigParser()
config["DEFAULT"] = {'ServerAliveInterval': '45',
                      'Compression': 'yes',
                     'CompressionLevel': '9'}
  
config['bitbucket.org'] = {}
config['bitbucket.org']['User'] = 'hg'
config['topsecret.server.com'] = {}
topsecret = config['topsecret.server.com']
topsecret['Host Port'] = '50022'     # mutates the parser
topsecret['ForwardX11'] = 'no'  # same here
config['DEFAULT']['ForwardX11'] = 'yes'
with open('example.ini', 'w') as configfile:
   config.write(configfile)

十三、ロギングモジュール

1. ログレベル

CRITICAL = 50 #FATAL = CRITICAL
ERROR = 40
WARNING = 30 #WARN = WARNING
INFO = 20
DEBUG = 10
NOTSET = 0 #不设置

2.デフォルト レベルは警告で、デフォルトで端末に出力されます。

import logging

logging.debug('调试debug')
logging.info('消息info')
logging.warning('警告warn')
logging.error('错误error')
logging.critical('严重critical')

'''
WARNING:root:警告warn
ERROR:root:错误error
CRITICAL:root:严重critical
'''

3. ロギング モジュールのグローバル構成を指定し、すべてのロガーに有効で、ファイルへの出力を制御します。

logging.basicConfig()関数では、特定のパラメータを使用してロギング モジュールのデフォルトの動作を変更できます. 使用可能なパラメータは filename です
: 指定されたファイル名で FiledHandler を作成します (ハンドラの概念については後で詳しく説明します) 、ログがファイルで指定された場所に保存されるようにします。
filemode: ファイルを開くモード。このパラメータは、ファイル名が指定されている場合に使用されます。デフォルト値は「a」で、「w」も指定できます。
format: ハンドラーが使用するログ表示形式を指定します。
datefmt: 日時形式を指定します。
level: rootlogger のログレベルを設定します (具体的な概念については後で説明します) 
stream: 指定されたストリームで StreamHandler を作成します。sys.stderr、sys.stdout、またはファイルへの出力を指定できます。デフォルトは sys.stderr です。ファイル名とストリーム パラメータの両方がリストされている場合、ストリーム パラメータは無視されます。
%(name)s ロガー名
%(levelno)s 数値形式のログ レベル


% 
(levelname)s テキスト形式のログ レベル
%(pathname)s ログ出力関数を呼び出すモジュール%(filename)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 ユーザーによるメッセージ出力がない可能性があります
#========使用
import logging
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)

logging.debug('调试debug')
logging.info('消息info')
logging.warning('警告warn')
logging.error('错误error')
logging.critical('严重critical')
#========结果
access.log内容:
2017-07-28 20:32:17 PM - root - DEBUG -test:  调试debug
2017-07-28 20:32:17 PM - root - INFO -test:  消息info
2017-07-28 20:32:17 PM - root - WARNING -test:  警告warn
2017-07-28 20:32:17 PM - root - ERROR -test:  错误error
2017-07-28 20:32:17 PM - root - CRITICAL -test:  严重critical

4. logging モジュールの Formatter、Handler、Logger、Filter オブジェクト

 覚えておく必要があるいくつかのパラメーター:

1.logger: ログを生成するオブジェクト

2.Filter: ログをフィルタリングするオブジェクト

3.Handler: ログを受信し、さまざまな場所への出力を制御します。FileHandler はファイルへの出力に使用され、StreamHandler はターミナルに出力し

ます

'''
critical=50
error =40
warning =30
info = 20
debug =10
'''


import logging

#1、logger对象:负责产生日志,然后交给Filter过滤,然后交给不同的Handler输出
logger=logging.getLogger(__file__)

#2、Filter对象:不常用,略

#3、Handler对象:接收logger传来的日志,然后控制输出
h1=logging.FileHandler('t1.log') #打印到文件
h2=logging.FileHandler('t2.log') #打印到文件
h3=logging.StreamHandler() #打印到终端

#4、Formatter对象:日志格式
formmater1=logging.Formatter('%(asctime)s - %(name)s - %(levelname)s -%(module)s:  %(message)s',  #打印到文件
                    datefmt='%Y-%m-%d %H:%M:%S %p',) 

formmater2=logging.Formatter('%(asctime)s :  %(message)s',  #打印到文件
                    datefmt='%Y-%m-%d %H:%M:%S %p',)

formmater3=logging.Formatter('%(name)s %(message)s',)  #打印到终端


#5、为Handler对象绑定格式
h1.setFormatter(formmater1)
h2.setFormatter(formmater2)
h3.setFormatter(formmater3)

#6、将Handler添加给logger并设置日志级别
logger.addHandler(h1)
logger.addHandler(h2)
logger.addHandler(h3)
logger.setLevel(10)

#7、测试
logger.debug('debug')
logger.info('info')
logger.warning('warning')
logger.error('error')
logger.critical('critical')

5、ロガーとハンドラーのレベル

ロガーはフィルタリングの最初のレベルであり、ハンドラーに到達できます.ロガーとハンドラーのレベルを同時に設定できますが、                                                                                                                                                         

import logging


form=logging.Formatter('%(asctime)s - %(name)s - %(levelname)s -%(module)s:  %(message)s',
                    datefmt='%Y-%m-%d %H:%M:%S %p',)

ch=logging.StreamHandler()

ch.setFormatter(form)
# ch.setLevel(10)
ch.setLevel(0)

l1=logging.getLogger('root')
# l1.setLevel(20)
l1.setLevel(10)
l1.addHandler(ch)  #发送的权限要在接收的权限里面,也就是发送的权限要比接收的权限要小

l1.debug('l1 debug')

6. 申請

1. アプリケーション 1

 ロガーを設定するために、最初にsetting.pyファイルを書きましょう

# -*- coding: utf-8 -*-

'''
@Time    : 2022/09/01 14:45
@Author  : Rice
@CSDN : C_小米同学
@FileName: setting.py
'''
"""
logging配置
"""

import os

# 1、定义三种日志输出格式,日志中可能用到的格式化串如下
# %(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用户输出的消息

# 2、强调:其中的%(name)s为getlogger时指定的名字
standard_format = '[%(asctime)s][%(threadName)s:%(thread)d][task_id:%(name)s][%(filename)s:%(lineno)d]' \
                  '[%(levelname)s][%(message)s]'

simple_format = '[%(levelname)s][%(asctime)s][%(filename)s:%(lineno)d]%(message)s'

test_format = '%(asctime)s] %(message)s'

# 3、日志配置字典
LOGGING_DIC = {
    'version': 1,
    'disable_existing_loggers': False,
    'formatters': {
        'standard': {
            'format': standard_format
        },
        'simple': {
            'format': simple_format
        },
        'test': {
            'format': test_format
        },
    },
    'filters': {},
    'handlers': {
        #打印到终端的日志
        'console': {
            'level': 'DEBUG',
            'class': 'logging.StreamHandler',  # 打印到屏幕
            'formatter': 'simple'
        },
        #打印到文件的日志,收集info及以上的日志
        'default': {
            'level': 'DEBUG',
            'class': 'logging.handlers.RotatingFileHandler',  # 保存到文件,日志轮转
            'formatter': 'standard',
            # 可以定制日志文件路径
            # BASE_DIR = os.path.dirname(os.path.abspath(__file__))  # log文件的目录
            # LOG_PATH = os.path.join(BASE_DIR,'a1.log')
            'filename': 'a1.log',  # 日志文件
            'maxBytes': 1024*1024*5,  # 日志大小 5M
            'backupCount': 5,
            'encoding': 'utf-8',  # 日志文件的编码,再也不用担心中文log乱码了
        },
        'other': {
            'level': 'DEBUG',
            'class': 'logging.FileHandler',  # 保存到文件
            'formatter': 'test',
            'filename': 'a2.log',
            'encoding': 'utf-8',
        },
    },
    'loggers': {
        #logging.getLogger(__name__)拿到的logger配置
        '''
        如果都没找到,则用空的'',key是用户提供的
        '''
        '': {
            'handlers': ['default', 'console'],  # 这里把上面定义的两个handler都加上,即log数据既写入文件又打印到屏幕
            'level': 'DEBUG', # loggers(第一层日志级别关限制)--->handlers(第二层日志级别关卡限制)
            'propagate': False,  # 默认为True,向上(更高level的logger)传递,通常设置为False即可,否则会一份日志向上层层传递
        },
        'kkk': {
            'handlers': ['default', 'console'],  # 这里把上面定义的两个handler都加上,即log数据既写入文件又打印到屏幕
            'level': 'DEBUG',  # loggers(第一层日志级别关限制)--->handlers(第二层日志级别关卡限制)
            'propagate': False,  # 默认为True,向上(更高level的logger)传递,通常设置为False即可,否则会一份日志向上层层传递
        },
        'bbb': {
            'handlers': ['default',],  # 这里把上面定义的两个handler都加上,即log数据既写入文件又打印到屏幕
            'level': 'DEBUG',  # loggers(第一层日志级别关限制)--->handlers(第二层日志级别关卡限制)
            'propagate': False,  # 默认为True,向上(更高level的logger)传递,通常设置为False即可,否则会一份日志向上层层传递
        },

        '专门的采集': {
            'handlers': ['other',],
            'level': 'DEBUG',
            'propagate': False,
        },
    },
}

次に、新しい src.py を作成して初期化し、ログを呼び出します

# -*- coding: utf-8 -*-

'''
@Time    : 2022/09/01 15:00
@Author  : Rice
@CSDN : C_小米同学
@FileName: src.py
'''


#拿到日志的产生者loggers-kkk/bbb
#先导入日志配置字典LOGGING_DIC
import setting
#import logging.config #注意,直接导入logging,然后在调config是不行的,这不是包,是文件,没有配置__init__文件

from logging import config,getLogger
#导入
config.dictConfig(setting.LOGGING_DIC)

# logger1 = getLogger('kkk')
#
# logger1.info('hello')  #info权限

logger2 = getLogger('bbb')
logger2.info('nihao')

  2. アプリケーション 2: シンプルなケース

"""
MyLogging Test
"""

import time
import logging
import my_logging  # 导入自定义的logging配置

logger = logging.getLogger(__name__)  # 生成logger实例


def demo():
    logger.debug("start range... time:{}".format(time.time()))
    logger.info("中文测试开始。。。")
    for i in range(10):
        logger.debug("i:{}".format(i))
        time.sleep(0.2)
    else:
        logger.debug("over range... time:{}".format(time.time()))
    logger.info("中文测试结束。。。")

if __name__ == "__main__":
    my_logging.load_my_logging_cfg()  # 在你程序文件的入口加载自定义logging配置
    demo()

14、再モジュール

1. 正規表現の紹介

正規化とは、特殊な意味を持ついくつかの記号 (正規表現と呼ばれる) を組み合わせて、文字または文字列を記述する方法です。言い換えれば、規則性は、物事のクラスを説明するために使用される規則です。(Python の場合) Python に組み込まれ、re モジュールを通じて実装されます。正規表現パターンは一連のバイトコードにコンパイルされ、C で記述されたマッチング エンジンによって実行されます。

2.よく使われるマッチングモード     

                             

# =================================匹配模式=================================
#一对一的匹配
# 'hello'.replace(old,new)
# 'hello'.find('pattern')

#正则匹配
import re
#\w与\W
print(re.findall('\w','hello egon 123')) #['h', 'e', 'l', 'l', 'o', 'e', 'g', 'o', 'n', '1', '2', '3']
print(re.findall('\W','hello egon 123')) #[' ', ' ']

#\s与\S
print(re.findall('\s','hello  egon  123')) #[' ', ' ', ' ', ' ']
print(re.findall('\S','hello  egon  123')) #['h', 'e', 'l', 'l', 'o', 'e', 'g', 'o', 'n', '1', '2', '3']

#\n \t都是空,都可以被\s匹配
print(re.findall('\s','hello \n egon \t 123')) #[' ', '\n', ' ', ' ', '\t', ' ']

#\n与\t
print(re.findall(r'\n','hello egon \n123')) #['\n']
print(re.findall(r'\t','hello egon\t123')) #['\n']

#\d与\D
print(re.findall('\d','hello egon 123')) #['1', '2', '3']
print(re.findall('\D','hello egon 123')) #['h', 'e', 'l', 'l', 'o', ' ', 'e', 'g', 'o', 'n', ' ']

#\A与\Z
print(re.findall('\Ahe','hello egon 123')) #['he'],\A==>^
print(re.findall('123\Z','hello egon 123')) #['he'],\Z==>$

 

指定匹配必须出现在字符串的开头或行的开头。

\A 
指定匹配必须出现在字符串的开头(忽略 Multiline 选项)。

$ 
指定匹配必须出现在以下位置:字符串结尾、字符串结尾的 \n 之前或行的结尾。

\Z 
指定匹配必须出现在字符串的结尾或字符串结尾的 \n 之前(忽略 Multiline 选项)。

#^与$
print(re.findall('^h','hello egon 123')) #['h']
print(re.findall('3$','hello egon 123')) #['3']

# 重复匹配:| . | * | ? | .* | .*? | + | {n,m} |
#.
print(re.findall('a.b','a1b')) #['a1b']
print(re.findall('a.b','a1b a*b a b aaab')) #['a1b', 'a*b', 'a b', 'aab']
print(re.findall('a.b','a\nb')) #[]
print(re.findall('a.b','a\nb',re.S)) #['a\nb']
print(re.findall('a.b','a\nb',re.DOTALL)) #['a\nb']同上一条意思一样

#*
print(re.findall('ab*','bbbbbbb')) #[]
print(re.findall('ab*','a')) #['a']
print(re.findall('ab*','abbbb')) #['abbbb']

#?
print(re.findall('ab?','a')) #['a']
print(re.findall('ab?','abbb')) #['ab']
#匹配所有包含小数在内的数字
print(re.findall('\d+\.?\d*',"asdfasdf123as1.13dfa12adsf1asdf3")) #['123', '1.13', '12', '1', '3']

#.*默认为贪婪匹配
print(re.findall('a.*b','a1b22222222b')) #['a1b22222222b']

#.*?为非贪婪匹配:推荐使用
print(re.findall('a.*?b','a1b22222222b')) #['a1b']

#+
print(re.findall('ab+','a')) #[]
print(re.findall('ab+','abbb')) #['abbb']

#{n,m}
print(re.findall('ab{2}','abbb')) #['abb']
print(re.findall('ab{2,4}','abbb')) #['abb']
print(re.findall('ab{1,}','abbb')) #'ab{1,}' ===> 'ab+'
print(re.findall('ab{0,}','abbb')) #'ab{0,}' ===> 'ab*'

#[]
print(re.findall('a[1*-]b','a1b a*b a-b')) #[]内的都为普通字符了,且如果-没有被转意的话,应该放到[]的开头或结尾
print(re.findall('a[^1*-]b','a1b a*b a-b a=b')) #[]内的^代表的意思是取反,所以结果为['a=b']
print(re.findall('a[0-9]b','a1b a*b a-b a=b')) #[]内的^代表的意思是取反,所以结果为['a=b']
print(re.findall('a[a-z]b','a1b a*b a-b a=b aeb')) #[]内的^代表的意思是取反,所以结果为['a=b']
print(re.findall('a[a-zA-Z]b','a1b a*b a-b a=b aeb aEb')) #[]内的^代表的意思是取反,所以结果为['a=b']

#\# print(re.findall('a\\c','a\c')) #对于正则来说a\\c确实可以匹配到a\c,但是在python解释器读取a\\c时,会发生转义,然后交给re去执行,所以抛出异常
print(re.findall(r'a\\c','a\c')) #r代表告诉解释器使用rawstring,即原生字符串,把我们正则内的所有符号都当普通字符处理,不要转义
print(re.findall('a\\\\c','a\c')) #同上面的意思一样,和上面的结果一样都是['a\\c']

#():分组
print(re.findall('ab+','ababab123')) #['ab', 'ab', 'ab']
print(re.findall('(ab)+123','ababab123')) #['ab'],匹配到末尾的ab123中的ab
print(re.findall('(?:ab)+123','ababab123')) #findall的结果不是匹配的全部内容,而是组内的内容,?:可以让结果为匹配的全部内容
print(re.findall('href="(.*?)"','<a href="http://www.baidu.com">点击</a>'))#['http://www.baidu.com']
print(re.findall('href="(?:.*?)"','<a href="http://www.baidu.com">点击</a>'))#['href="http://www.baidu.com"']

#|
print(re.findall('compan(?:y|ies)','Too many companies have gone bankrupt, and the next one is my company'))
# ===========================re模块提供的方法介绍===========================
import re
#1
print(re.findall('e','alex make love') )   #['e', 'e', 'e'],返回所有满足匹配条件的结果,放在列表里
#2
print(re.search('e','alex make love').group()) #e,只到找到第一个匹配然后返回一个包含匹配信息的对象,该对象可以通过调用group()方法得到匹配的字符串,如果字符串没有匹配,则返回None。

#3
print(re.match('e','alex make love'))    #None,同search,不过在字符串开始处进行匹配,完全可以用search+^代替match

#4
print(re.split('[ab]','abcd'))     #['', '', 'cd'],先按'a'分割得到''和'bcd',再对''和'bcd'分别按'b'分割

#5
print('===>',re.sub('a','A','alex make love')) #===> Alex mAke love,不指定n,默认替换所有
print('===>',re.sub('a','A','alex make love',1)) #===> Alex make love
print('===>',re.sub('a','A','alex make love',2)) #===> Alex mAke love
print('===>',re.sub('^(\w+)(.*?\s)(\w+)(.*?\s)(\w+)(.*?)$',r'\5\2\3\4\1','alex make love')) #===> love make alex

print('===>',re.subn('a','A','alex make love')) #===> ('Alex mAke love', 2),结果带有总共替换的个数


#6
obj=re.compile('\d{2}')

print(obj.search('abc123eeee').group()) #12
print(obj.findall('abc123eeee')) #['12'],重用了obj

 

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             

 

おすすめ

転載: blog.csdn.net/weixin_43507744/article/details/126625982