python內(nèi)置模塊與第三方模塊(庫)

@[toc]

1. 模塊

模塊可以是一個python文件也可以是文件夾。

1.1 內(nèi)置模塊

python模塊內(nèi)部提供的功能

# coding:utf-8
import sys

print(sys.argv)
1.2 第三方模塊

安裝:<kbd>pip/pip3 install 需要安裝的模塊</kbd> [https://pypi.org/]

1.3 自定義模塊

自己創(chuàng)建文件或者文件夾(這個文件夾也可以稱為包,包中有 _ _ init _ _.py文件)

'''
自定義模塊
'''
# coding:utf-8
def f1():
    print('f1')
def f2():
    print('f2')
'''
調(diào)用自定義模塊
'''
# coding:utf-8
import modules

modules.f1()
modules.f2()
'''
f1
f2
'''
1.4 模塊的定義

定義一個模塊時,可以把一個一個python文件或一個文件夾(包)當(dāng)作一個模塊,放方便以后其它python文件調(diào)用。
注意:對包的定義,python2中必須要有_ _ init _ _.py文件;python3中不需要這個文件。不論python2還是python3都要加上這個文件。

1.5 模塊的導(dǎo)入

① 模塊導(dǎo)入方式一:<kbd>import 模塊</kbd>,<kbd>模塊.函數(shù)()</kbd>

# 導(dǎo)入模塊,加載此模塊中所有值到內(nèi)存(執(zhí)行requests.py文件并加載到內(nèi)存)
import requests  # 執(zhí)行requests.py文件并加載到內(nèi)存

② 模塊導(dǎo)入方式二:<kbd>from 模塊 import 函數(shù)或者*</kbd>,<kbd>函數(shù)()</kbd>

from time import time
from time import strftime
from time import time, strftime(推薦用這種,減少代碼量)
from time import * # 導(dǎo)入所有功能

③ 模塊導(dǎo)入方式三:<kbd>from 模塊 import 函數(shù) as 別名</kbd>,<kbd>別名()</kbd>

模塊導(dǎo)入方式二可能會出縣如下問題:

from time import time

def time():  # 自己寫的time函數(shù)把導(dǎo)入的time函數(shù)覆蓋
    print('kiku')
time()

可以給導(dǎo)入的模塊起別名:<kbd>from time import time as t</kbd>

注意:如果存在包,可以采用下面的導(dǎo)入方式:

<kbd>from xxx.xx import x</kbd>

<kbd>import xxx.xx.x</kbd>

xxx是包(文件夾),xx是python文件,x是函數(shù)。

④ 相對導(dǎo)入

示例一:


在這里插入圖片描述

<kbd>run.py</kbd>

from src import module01
if __name__ == '__main__':
    module01.foo()

<kbd>module01.py</kbd>

from . import module02

def foo():
    print('module01')
    module02.foo()

<kbd>module02.py</kbd>

def foo():
    print('module02')

示例二:


在這里插入圖片描述

<kbd>run.py</kbd>

import module01

if __name__ == '__main__':
    module01.foo()

<kbd>module01.py</kbd>

from . import module02

def foo():
    print('module01')
    module02.foo()

<kbd>module02.py</kbd>

def foo():
    print('module02')

使用<kbd>from . import module02</kbd>報錯:<kbd>ImportError: attempted relative import with no known parent package</kbd>,相對導(dǎo)入至少需要兩個python文件在同一個包中。如:


在這里插入圖片描述

在這里插入圖片描述

⑤ 模塊導(dǎo)入總結(jié)

  • 模塊和要執(zhí)行的python文件在同一目錄,需要模塊中很多功能時,推薦使用:<kbd>import 模塊</kbd>
  • 除此之外,推薦使用:<kbd>from 模塊 import 模塊</kbd>,<kbd>模塊.函數(shù)()</kbd>
  • 除此之外,推薦使用:<kbd>from 模塊.模塊 import 函數(shù)</kbd>,<kbd>函數(shù)()</kbd>

⑥ 導(dǎo)入模塊練習(xí)題

練習(xí)一:運行某個腳本(python文件),python文件所在的目錄會被放到<kbd>sys.path</kbd>中。


在這里插入圖片描述

<kbd>run.py</kbd>:

'''
運行的使run.py文件,會將E:\pycharmProjects\practice\lib路徑加入到sys.path中,所以lib目錄下的文件,可以直接導(dǎo)入
'''
import client
'''
client module!
'''

<kbd>client.py</kbd>:

print('client module!')
  • 練習(xí)二

目錄結(jié)構(gòu):


在這里插入圖片描述

<kbd>run.py</kbd>:

'''
如果要在run.py中導(dǎo)入test.py模塊
'''
import os

print(__file__)  # __file__是當(dāng)前運行腳本所在的路徑:E:/pycharmProjects/practice/lib/run.py
v = os.path.dirname(__file__)
print(v)  # E:/pycharmProjects/practice/lib
v2 = os.path.dirname(v)
print(v2)  # E:/pycharmProjects/practice

import test
'''
E:/pycharmProjects/practice/lib/run.py
E:/pycharmProjects/practice/lib
E:/pycharmProjects/practice
test module!
'''

<kbd>test.py</kbd>

print('test module!')
  • 練習(xí)三

修改<kbd>runn.py</kbd>:

print(__file__)

當(dāng)在run.py所在的文件夾lib中,執(zhí)行<kbd>python ./run.py</kbd>,得到結(jié)果是<kbd>./run.py
</kbd>。也就是說,__ file __并不是是當(dāng)前運行腳本所在的路徑(在這里糾正練習(xí)二中的錯誤),而只是路徑參數(shù)。如何解決這個問題?其實,我們可以絕對路徑,<kbd>os.path.abspath()</kbd>

import os, sys

# print(__file__)  # __file__是當(dāng)前運行腳本所在的路徑參數(shù):E:/pycharmProjects/practice/lib/run.py
# print(os.path.abspath(__file__))  # E:\pycharmProjects\practice\lib\run.py
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
# print(v)  # E:\pycharmProjects\practice
'''
將E:\pycharmProjects\practice加入sys.path中
'''
sys.path.append(BASE_DIR)
import test

'''
test module!
'''
2. 內(nèi)置模塊
2.1 sys

sys模塊中包含pthon解釋器相關(guān)的數(shù)據(jù)。

① 引用次數(shù)
<kbd>sys.getrefcount()</kbd>:獲取一個值的應(yīng)用計數(shù)

''''
sys模塊中,pthon解釋器相關(guān)的數(shù)據(jù)
獲取一個值的應(yīng)用計數(shù)
'''
import sys
a = [1,2,3]
b=a
print(sys.getrefcount(a))
'''
3
'''

② 遞歸次數(shù)
<kbd>sys.getrecursionlimit()</kbd>:獲取python默認(rèn)支持的遞歸數(shù)量

''''
sys模塊中,pthon解釋器相關(guān)的數(shù)據(jù)
python默認(rèn)支持的遞歸數(shù)量
'''
import sys
print(sys.getrecursionlimit())
'''
1000
'''

③ 輸出

<kbd>sys.stdout.write()</kbd>:輸出,print函數(shù)內(nèi)部會調(diào)用它

''''
輸入輸出:print函數(shù)內(nèi)部會調(diào)用
'''
import sys

# 不能是數(shù)字,只能是字符串。默認(rèn)不換行,print函數(shù)內(nèi)部會調(diào)用它。
sys.stdout.write('520')
sys.stdout.write('kiku')
'''
520kiku
'''

進(jìn)度條的實現(xiàn)

# \n:換行
# \t:制表符
# \r:回到當(dāng)前行的起始位置
print('thanlon', end='')
print('kiku')

print('thanlon\r', end='')
print('kiku')
'''
thanlonkiku
kiku
'''
# coding:utf-8
'''
使用\r做進(jìn)度條
'''
import time

for i in range(1, 101):
    msg = '%s%%\r' % i
    print(msg, end='')
    time.sleep(0.05)
'''
100%
'''

\r的應(yīng)用:進(jìn)度條的實現(xiàn)(讀文件)

# coding:utf-8
'''
進(jìn)度條
'''
import os

# 讀取文件的大小(字節(jié)大小)
file_size = os.stat('video.mp4').st_size
# 一點一點讀文件
read_size = 0
with open('video.mp4', mode='rb') as f1, open('tmp.mp4', mode='wb')as f2:
    while read_size < file_size:
        chunk = f1.read(1024)  # 每次最多讀取1024字節(jié)
        f2.write(chunk)
        read_size += len(chunk)
        v = int(read_size / file_size * 100)
        print('%s%%\r' % v, end='')
在這里插入圖片描述

④ 獲取用戶的執(zhí)行腳本的路徑

<kbd>sys.argv</kbd>:獲取用戶的執(zhí)行腳本的路徑

# coding:utf-8
import sys

print(sys.argv)
'''
['E:/pycharmProjects/untitled/test.py']
'''
# coding:utf-8
'''
讓用戶執(zhí)行腳本傳入要刪除的文件路徑,在內(nèi)部幫助用戶將目錄刪除
'''
import sys

'''
獲取用戶執(zhí)行的腳本時,傳入?yún)?shù)
如:D:\Python37\python.exe E:/pycharmProjects/untitled/test.py D:/test(參數(shù)是“D:/test”)
sys.argv = ['E:/pycharmProjects/untitled/test.py', 'D:/test']
'''
# 獲取參數(shù)
path = sys.argv[1]  # path =D:/test
# 刪除文件目錄
import shutil

shutil.rmtree(path)

⑤ 模塊的查找路徑

<kbd>sys.path</kbd>:默認(rèn)python去導(dǎo)入模塊,會按照sys.path中的路徑依次查找。

import sys

for i in sys.path:
    print(i)
'''
'''
E:\pycharmProjects\practice # 執(zhí)行py文件會向sys.path中添加一個路徑,可忽略。D:\Python37\python.exe E:/pycharmProjects/practice/test.py
E:\pycharmProjects\practice # 把當(dāng)前pycharm中project路徑也添加到sys.path中,可忽略。
C:\Program Files\JetBrains\PyCharm 2019.1.3\helpers\pycharm_display
D:\Python37\python37.zip
D:\Python37\DLLs
D:\Python37\lib
D:\Python37
D:\Python37\lib\site-packages
D:\Python37\lib\site-packages\turtle-0.0.2-py3.7.egg
D:\Python37\lib\site-packages\pyyaml-5.1.1-py3.7-win-amd64.egg
C:\Program Files\JetBrains\PyCharm 2019.1.3\helpers\pycharm_matplotlib_backend # pycharm中添加的,忽略
'''
'''

注意內(nèi)置模塊,使用

D:\Python37\python37.zip
D:\Python37\DLLs
D:\Python37\lib
D:\Python37
D:\Python37\lib\site-packages
D:\Python37\lib\site-packages\turtle-0.0.2-py3.7.egg
D:\Python37\lib\site-packages\pyyaml-5.1.1-py3.7-win-amd64.egg

這幾個模塊,不要把自定義模塊(自己寫模塊)寫到這些文件中,python一旦卸載,這些模塊也會清除。
如果非要向path中添加路徑,可以向path中添加導(dǎo)入模塊的路徑:

import sys

sys.path.append(r'D:/')
print(sys.path)
2.2 os

① os模塊作用
可以獲取與操作系統(tǒng)之間的數(shù)據(jù)

② 文件是否存在

# coding:utf-8
import os

if os.path.exists('E:\pycharmProjects\practice\log.txt'):
    print('yes!')
'''
yes!
'''

③ 獲取文件的大小
os.stat('E:\pycharmProjects\practice\log.txt').st_size

# coding:utf-8
import os

v = os.stat('E:\pycharmProjects\practice\log.txt').st_size  # 字節(jié)
print(v)  # 9

④ 獲取文件的絕對路徑
os.path.abspath(path)

# coding:utf-8
import os

path = 'log.txt'
v = os.path.abspath(path)
print(v)
'''
E:\pycharmProjects\practice\log.txt
'''

⑤ 獲取文件或目錄的上一級目錄
os.path.dirname(path)

# coding:utf-8
import os

path = 'E:\pycharmProjects\practice\log.txt'
path2 = 'E:\pycharmProjects\practice\test'
v = os.path.dirname(path)  # E:\pycharmProjects\practice
v2 = os.path.dirname(path2)  # E:\pycharmProjects\practice
print(v)
print(v2)
'''
E:\pycharmProjects\practice
E:\pycharmProjects
'''

⑥ 路徑的拼接
os.path.join(file_name, path)

# coding:utf-8
import os

path = 'E:\pycharmProjects\practice'
file_name = 'log.txt'
res1 = os.path.join(file_name, path)  # 注意順序
res2 = os.path.join(path, file_name)
res3 = os.path.join(path, 'test', file_name)
print(res1)
print(res2)
print(res3)
'''
E:\pycharmProjects\practice
E:\pycharmProjects\practice\log.txt
E:\pycharmProjects\practice\test\log.txt
'''

⑦ 獲取一個目錄下所有的文件[第一層](面試)
os.listdir(r'E:\pycharmProjects\practice\test')

# coding:utf-8
import os

res = os.listdir(r'E:\pycharmProjects\practice\test')
print(res)  # ['index.html', 'log.txt']
for item in res:
    print(item)
'''
index.html
log.txt
'''

⑧ 獲取一個目錄下所有的文件[所有層](面試)

# coding:utf-8
import os

res = os.walk(r'E:\pycharmProjects\practice')
print(res)  # <generator object walk at 0x00000237D9C85570>生成器
# coding:utf-8
import os

res = os.walk(r'E:\pycharmProjects\practice')

for item in res:
    print(item)
'''
('E:\\pycharmProjects\\practice', ['.idea', 'test'], ['test.py'])
('E:\\pycharmProjects\\practice\\.idea', [], ['misc.xml', 'modules.xml', 'practice.iml', 'workspace.xml'])
('E:\\pycharmProjects\\practice\\test', [], ['index.html', 'log.txt'])
'''
# coding:utf-8
import os

res = os.walk(r'E:\pycharmProjects\practice')

for a, b, c in res:
    '''
    a:正在查看的目錄
    b:此目錄下的文件夾
    c:此目錄下的文件
    '''
    print(a)
    print(b)
    print(c)
    '''
    E:\pycharmProjects\practice
    ['.idea', 'test']
    ['test.py']
    E:\pycharmProjects\practice\.idea
    []
    ['misc.xml', 'modules.xml', 'practice.iml', 'workspace.xml']
    E:\pycharmProjects\practice\test
    []
    ['index.html', 'log.txt']
    '''

面試題:找到目錄中的所有文件(重點)

# coding:utf-8
import os

res = os.walk(r'E:\pycharmProjects\practice')

for a, b, c in res:
    '''
    a:正在查看的目錄
    b:此目錄下的文件夾
    c:此目錄下的文件
    '''
    # print(a)
    # print(b)
    # print(c)
    '''
    E:\pycharmProjects\practice
    ['.idea', 'test']
    ['test.py']
    E:\pycharmProjects\practice\.idea
    []
    ['misc.xml', 'modules.xml', 'practice.iml', 'workspace.xml']
    E:\pycharmProjects\practice\test
    []
    ['index.html', 'log.txt']
    '''
    for item in c:
        path = os.path.join(a, item)
        print(path)
    '''
    E:\pycharmProjects\practice\test.py
    E:\pycharmProjects\practice\.idea\misc.xml
    E:\pycharmProjects\practice\.idea\modules.xml
    E:\pycharmProjects\practice\.idea\practice.iml
    E:\pycharmProjects\practice\.idea\workspace.xml
    E:\pycharmProjects\practice\test\index.html
    E:\pycharmProjects\practice\test\log.txt
    '''

⑨ 補充:字符串轉(zhuǎn)義

v1 = 'E:\pycharmProjects\practice\\nxl'
v2 = r'E:\pycharmProjects\practice\nxl'  # 推薦使用
2.3 json

① json簡介
json是一個特殊的字符串,與python中的list/dict/str/int/bool很像

② 序列化與反序列化
序列化,將python的值轉(zhuǎn)換為json格式的字符串:

import json

v = [1, 2, 3, 'thanlon', True, {'name': 'thanlon', 'age': 23}]
# 序列化,將python的值轉(zhuǎn)換為json格式的字符串
v2 = json.dumps(v)
print(v2)
'''
[1, 2, 3, "thanlon", true, {"name": "thanlon", "age": 23}]
'''

反序列化,將json格式的字符串轉(zhuǎn)換成python的數(shù)據(jù)類型:

import json

v = '["thanlon",23]'
# 反序列化,將json格式的字符串轉(zhuǎn)換成python的數(shù)據(jù)類型
v2 = json.loads(v)
print(v2)
'''
['thanlon', 23]
'''

注意:不能序列化元組,會把元組變?yōu)榱斜?/p>

import json

v = ('thanlon', 23)
v2 = json.dumps(v)
print(type(v2), v2)
'''
<class 'str'> ["thanlon", 23]
'''

注意:不能序列化集合,會報錯

import json

v = {'thanlon', 23}
# 反序列化,將json格式的字符串轉(zhuǎn)換成python的數(shù)據(jù)類型
v2 = json.dumps(v)
'''
TypeError: Object of type set is not JSON serializable
'''

支持序列化位json字符串的數(shù)據(jù)類型:

來自encoder.py文件:
    +-------------------+---------------+
    | Python            | JSON          |
    +===================+===============+
    | dict              | object        |
    +-------------------+---------------+
    | list, tuple       | array         |
    +-------------------+---------------+
    | str               | string        |
    +-------------------+---------------+
    | int, float        | number        |
    +-------------------+---------------+
    | True              | true          |
    +-------------------+---------------+
    | False             | false         |
    +-------------------+---------------+
    | None              | null          |
    +-------------------+---------------+

json字符串中需要構(gòu)造成列表或字典(包裹其它內(nèi)容)才可以被反序列化,傳一個值也要構(gòu)造成列表或字典:

import json
'''
list或dict包裹的內(nèi)容才可以反序列化,只有字符串是不可以反序列化的
'''
v = 'thanlon'
v2 = json.loads(v)
print(v2)
'''
json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)
'''

③ dump與load(幾乎不常用)

  • dump:序列化后寫入文件
# coding:utf-8
import json

v = [1, 2, 3]
f = open('test.txt', mode='w', encoding='utf-8')
val = json.dump(v, f)
print(val)
  • load:讀取文件數(shù)據(jù)并反序列化
# coding:utf-8
import json

f = open('test.txt', mode='r', encoding='utf-8')
val = json.load(f)
print(val)
'''[1, 2, 3]'''

④ json模塊補充

序列化字典的時候,如果字典中有中文,在序列化為json格式字符串時需要保留中文,需要這樣做:

# coding:utf-8
import json

v = {'k1': '奈何', '哈哈': 'v2'}
val = json.dumps(v)  # 默認(rèn)中文是unicode編碼的
print(val)
'''
{"k1": "\u5948\u4f55", "\u54c8\u54c8": "v2"}
'''
val2 = json.dumps(v, ensure_ascii=False)
print(val2)
'''
{"k1": "奈何", "哈哈": "v2"}
'''

總結(jié):字典或列表中如果有中文,序列化時想要保留中文顯示,可以使<kbd>ensure_ascii=False</kbd>

2.4 pickle

① json與pickle

  • json優(yōu)缺點
    優(yōu)點:所有語言通用
    缺點:只能序列化基本數(shù)據(jù)類型 list/dict/int
  • pickle優(yōu)缺點
    優(yōu)點:python中所有東西都能被序列化(socket對象除外)
    缺點:序列化的內(nèi)容只有python語言能識別

② dumps/loads

<kbd>dumps函數(shù)</kbd>:用于將數(shù)據(jù)進(jìn)行序列化,完成序列化后,會把數(shù)據(jù)轉(zhuǎn)換成字節(jié),是不可識別的。

<kbd>loads函數(shù)</kbd>:用于反序列化

示例:集合的序列化與反序列化:

# coding:utf-8
'''
集合的序列化與反序列化
'''
import pickle

v = {1, 2, 3, 4}
val = pickle.dumps(v)
print(val)
'''
b'\x80\x03cbuiltins\nset\nq\x00]q\x01(K\x01K\x02K\x03K\x04e\x85q\x02Rq\x03.'
'''
data = pickle.loads(val)
print(data)
'''
{1, 2, 3, 4}
'''

示例:函數(shù)的序列化與反序列化:

# coding:utf-8
'''
函數(shù)的序列化與反序列化
'''
import pickle

def foo():
    print('foo')

v1 = pickle.dumps(foo)
print(v1)
data = pickle.loads(v1)
data()
'''
b'\x80\x03c__main__\nfoo\nq\x00.'
foo
'''

③ dump/load

<kbd>dumps函數(shù)</kbd>:對數(shù)據(jù)進(jìn)行序列化,同時可以保存序列化的內(nèi)容(序列化后寫入文件)

<kbd>loads函數(shù)</kbd>:讀取文件數(shù)據(jù)并反序列化

# coding:utf-8
'''
dump/load:
'''
import pickle

v = {1, 2, 3, 4}
f1 = open('test.txt', mode='wb')
val = pickle.dump(v, f1)  # 寫入文件的時候?qū)懭氲氖亲止?jié)類型的數(shù)據(jù)
f1.close()
f2 = open('test.txt', mode='rb')
data = pickle.load(f2)
f2.close()
print(data)
'''
{1, 2, 3, 4}
'''
2.5 shutil

① 刪除目錄(常用)
os模塊的刪除可能會出問題,可能是權(quán)限的問題。文件夾中不能有文件,有文件就刪除不了。 而shutil模塊,強制刪除(文件和目錄一塊被刪除)。

# coding:utf-8
import shutil
# 刪除目錄
shutil.rmtree('test')  # 不能刪除文件

② 重命名目錄和文件(常用)

# coding:utf-8
import shutil

# 重命名目錄和文件
shutil.move('test', 'tmp')
shutil.move('test.txt', 'tmp.txt')

③ 壓縮(常用)

# coding:utf-8
import shutil

# 壓縮
shutil.make_archive('test', 'zip', 'test')  # "zip", "tar", "gztar","bztar", or "xztar"
# shutil.make_archive('test', 'zip', 'E:\pycharmProjects\\untitled\\test')

④ 解壓(常用)

# coding:utf-8
import shutil

# 解壓到當(dāng)前目錄
shutil.unpack_archive('test.zip', format='zip')  # 解壓到當(dāng)前目錄
# 解壓到指定目錄,指定目錄如果沒有,可以創(chuàng)建
shutil.unpack_archive('test.zip', extract_dir='D:\\newdir', format='zip')

⑤ 將一個文件內(nèi)容拷貝到另一個文件中

# coding:utf-8
import shutil

# 將一個文件內(nèi)容拷貝到另一個文件中
shutil.copyfileobj(open('test.txt', 'r'), open('log.txt', 'w'))

⑥ 拷貝文件

# coding:utf-8
import shutil

# 拷貝文件
shutil.copyfile('test.txt','log.txt')
2.6 time

① time模塊的基本使用

# coding:utf-8
import os, shutil
from datetime import datetime

ctime = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
print(ctime)  # 2019-08-01 16:59:42

② time模塊相關(guān)

UTC/GMP:世界協(xié)調(diào)時間(UTF比GMP精度高)
本地時間:本地時區(qū)的時間

  • time.time():時間戳(1070-1-1 00:00)
  • time.sleep(10):等待的時間(秒)
  • time.timezone:當(dāng)前時區(qū)和格林尼治時間相差的秒數(shù)

③ time模塊綜合案例

# coding:utf-8
'''
1. 壓縮test文件夾
2. 將壓縮的文件放到tmp目錄下(默認(rèn)tmp目錄不存在)
3. 將文件解壓到D:\tmp文件夾下
'''
import os, shutil
from datetime import datetime

if not os.path.exists('tmp'):
    os.mkdir('tmp')
ctime = datetime.now().strftime('%Y-%m-%d-%H-%M-%S')  # ctime是字符串
path = os.path.join('tmp', ctime)  # 字符串,tmp\2019-08-01-16-48-46
shutil.make_archive(os.path.join('tmp', ctime), 'zip', r'E:\pycharmProjects\untitled\test')  # 將test壓縮到tmp目錄下
file_path = os.path.join('tmp', ctime) + '.zip'
shutil.unpack_archive(file_path, r'D:\tmp', 'zip')  # 文件夾tmp沒有自動創(chuàng)建
2.7 datetime

① 獲取本地時間(重要)

from datetime import datetime

print(datetime.now()) # datatime類型
'''
2019-08-03 13:12:10.326124
'''

② 獲取UTC時間(重要)

from datetime import datetime

print(datetime.utcnow())
'''
2019-08-03 05:15:04.251507
'''

③ 獲得時區(qū)

from datetime import timezone, timedelta

tz = timezone(timedelta(hours=1))  # 獲取時區(qū),hours表示一小時間隔,表示東一區(qū)。西一區(qū)可以使用-1
print(tz)
'''
UTC+01:00
'''

④ 獲取指定時區(qū)時間

from datetime import timezone, timedelta, datetime

tz = timezone(timedelta(hours=1))  # 獲取時區(qū)
t = datetime.now(tz)
print(t)
'''
2019-08-03 06:27:31.913264+01:00
'''

⑤ datetime類型轉(zhuǎn)換成字符串

from datetime import datetime

v1 = datetime.now()
print(v1, type(v1))  # 2019-08-03 13:39:09.383417 <class 'datetime.datetime'>
val = v1.strftime('%Y-%m-%d %H:%M%S')  # 字符串中不能使用中文字符
print(val)

⑥ 字符串轉(zhuǎn)換成datetime

from datetime import datetime

v = datetime.strptime('2019-8-1', '%Y-%m-%d')  # '2019-8-1'與'2019-08-01'
print(v, type(v))
'''
2019-08-01 00:00:00 <class 'datetime.datetime'>
'''

⑦ datetime類型時間的加減

from datetime import datetime, timedelta

# v = datetime.strptime('2019-8-1', '%Y-%m-%d')  # '2019-8-1'與'2019-08-01'同沒有寫時間,使用00:00:00
time_str = datetime.now().strftime('%Y-%m-%d %H:%M:%S')  # 獲取當(dāng)前時間
v = datetime.strptime(time_str, '%Y-%m-%d %H:%M:%S')  #
val = v + timedelta(hours=24)  # 增加20個小時,也可以減;不加參數(shù),默認(rèn)是增加的是天數(shù)
time_str2 = val.strftime('%Y-%m-%d %H:%M:%S')
print(v)
print(val)
print(time_str2, type(time_str2))  # 使用datetime類型去做加減,最后要把datetime類型轉(zhuǎn)換成字符串
'''
2019-08-03 14:11:19
2019-08-04 10:11:19
'''

⑧ 時間戳和datetime相互轉(zhuǎn)換

  • 時間戳轉(zhuǎn)換為datatime類型的時間
from datetime import datetime
import time

ctime = time.time()
print(ctime, type(ctime))
v = datetime.fromtimestamp(ctime)
print(v, type(v))
'''
1564813290.9766583 <class 'float'>
2019-08-03 14:21:30.976658 <class 'datetime.datetime'>
'''
  • datetime類型轉(zhuǎn)換為時間戳類型
from datetime import datetime
import time

v = datetime.now()
val = v.timestamp()
print(val, type(val))
'''
1564813408.263414 <class 'float'>
'''

⑨ time與datetime模塊知識總結(jié)
總結(jié):時間分為time和datetime,time中有一個時間戳類型時間,datetime中有datetime類型和字符串類型的時間。time可以與datetime相互轉(zhuǎn)換,字符串一般用于頁面顯示以及文件的存儲,如果想用隨機值使用時間戳。datetime類型的時間可以做加減乘除運算。時間戳轉(zhuǎn)換為datetime類型使用fromtimestamp方法,datetime類型可以轉(zhuǎn)換為timestamp方法。datetime轉(zhuǎn)換成字符串使用strftime方法,字符串轉(zhuǎn)換為datetime類型使用strptime方法。datetime中時間的加減乘除使用timedelta。一般用時間戳和時間字符串多一些。

2.8 logging
# coding:utf-8
import logging
import traceback

# basicConfig函數(shù)的功能是:為日志系統(tǒng)做基礎(chǔ)的配置
# print(logging.__dir__())  # 打印模塊中的方法
'''
asctime:時間
name:用戶
levelname:級別
module:運行的模塊
message:相關(guān)信息
'''
logger = logging.basicConfig(
    filename='log.txt',
    format='%(asctime)s - %(name)s - %(levelname)s - %(module)s:%(message)s',
    datefmt='%Y-%m-%d %H:%M:%S',
    level=30)  # level>=30才會被寫入日志文件,默認(rèn)級別是30


# 級別大于basicConfig函數(shù)中設(shè)置的級別才可以被寫入日志文件,內(nèi)部都自帶級別
# CRITICAL = 50
# FATAL = CRITICAL
# ERROR = 40
# WARNING = 30
# WARN = WARNING
# INFO = 20
# DEBUG = 10
# NOTSET = 0

# logging.debug('debug')
# logging.info('info')
# logging.warning('warning')
# logging.error('error')
# logging.critical('critical')
# logging.fatal('error')  # fatal函數(shù)等價于critical函數(shù)

# logging.log(10, 'debug')  # debug
# logging.log(20, 'info')  # info
# logging.log(30, 'warning')  # warning
# logging.log(40, 'error')  # error
# logging.log(50, 'critical')  # critical/fatal

def func():
    a = 10
    try:
        b = a / 0
    except Exception as e:
        # print(e)  # print函數(shù)內(nèi)部調(diào)用str方法將對象轉(zhuǎn)換成字符串打印出來

        '''
        只是將e的信息寫入日志,這是不夠的
        '''
        # logging.error(str(e))
        '''
        需要更加具體到錯誤的代碼行數(shù)
        '''
        msg = traceback.format_exc()
        logging.error(msg)
        '''
        log.txt文件:
        2019-07-03 23:32:01 - root - ERROR - logTest:Traceback (most recent call last):
          File "E:/pycharmProjects/day15/logTest.py", line 48, in func
            b = a / 0
        ZeroDivisionError: division by zero
        '''
func()
2.9 md5加密

① 簡單的加密

import hashlib

# 實例化對象
obj = hashlib.md5()
# 寫入要加密的字節(jié),python3中加密的必須是字節(jié)
obj.update('123456'.encode('utf-8'))
# 獲取密文
ciphers = obj.hexdigest()
print(ciphers)
'''e10adc3949ba59abbe56e057f20f883e'''

如果撞庫(將能想到的常用的密碼加密,根據(jù)密文找明文),密碼可能不安全。

② 加鹽實現(xiàn)加密
使用加鹽可以解決撞庫問題,增強密碼的安全性。

# 使用加鹽解決撞庫
import hashlib

# 實例化對象
obj = hashlib.md5(b'thanlon')  # 加鹽
# 寫入要加密的字節(jié),python3中加密的必須是字節(jié)
obj.update('123456'.encode('utf-8'))
# 獲取密文
ciphers = obj.hexdigest()
print(ciphers)
'''1a8c227a607ed3c09a39f4b6a6df8869'''

③ MD5加密的應(yīng)用(自定義MD5函數(shù))
定義自己的MD5加密函數(shù),方便應(yīng)用到自己的項目中:

import hashlib

SALT = b'thanlon'

# 自定義MD5函數(shù)
def md5(pwd):
    obj = hashlib.md5(SALT)
    # pwd是字符串,需要將其轉(zhuǎn)換成字節(jié)
    obj.update(pwd.encode('utf-8'))
    # 返回密文
    return obj.hexdigest()
    
print(md5('123456'))
2.10 getpass

getpass模塊可以讓用戶在終端輸入密碼不顯示,注意只有在終端運行密碼才會不顯示。

import getpass

pwd = getpass.getpass('請輸入密碼:')
if pwd == '123456':
    print('密碼正確!')
2.11 csv

① csv概述
csv:逗號分隔值(comma-separated values),有時也稱為字符分割值,以純文本形式存儲表格數(shù)據(jù)(數(shù)字和文本)。
創(chuàng)建csv文件:在Microsoft Excel中船艦表格,另存為csv格式的文件,


在這里插入圖片描述

輸入如下數(shù)據(jù):


在這里插入圖片描述

② csv文件的讀取
import csv

with open('stuInfo.csv', 'r') as f:
    data = csv.reader(f)
    # print(data)  # data is a object<_csv.reader object at 0x00000197FC4A4160>
    # for data_item in data:
    #     print(data_item)
    # ['1', 'thanlon', '10000']
    # ['2', 'Maria', '20000']
    for data_item in data:
        print(data_item[0], data_item[1], data_item[2])
'''
1 thanlon 10000
2 Maria 20000
'''

③ csv文件的寫入

import csv

stu = ['3', 'Maria', 10000]
with open('stuInfo.csv', 'a', newline='') as f:  # 如果沒有加newline=''寫入一行后空行
    csv_writer = csv.writer(f, dialect='excel')
    csv_writer.writerow(stu)

with open('stuInfo.csv', 'r') as f:
    data = csv.reader(f)
    for data_item in data:
        print(data_item[0], data_item[1], data_item[2])
'''
1 thanlon 10000
2 Maria 20000
3 Maria 10000
'''
2.12 timeit

timeit模塊可以用來計算代碼執(zhí)行的時間。

① timeit函數(shù)
timeit模塊的timeit函數(shù)其實返回的是timerit模塊中Timer類的timeit方法的執(zhí)行結(jié)果,timeit函數(shù)的源碼:

def timeit(stmt="pass", setup="pass", timer=default_timer,
           number=default_number, globals=None):
    """Convenience function to create Timer object and call timeit method."""
    return Timer(stmt, setup, timer, globals).timeit(number)

參數(shù):

  • stmt:用來放需要進(jìn)行計算時間的代碼,可以接收字符串的表達(dá)式、單個變量、函數(shù)。
  • setup:可以用來傳stmt的環(huán)境,例如import和一些參數(shù)之類的。
  • number:執(zhí)行是的次數(shù),默認(rèn)是1000000
  • 其它參數(shù)一般用不到,具體可查看文檔

返回值:

  • timeit函數(shù)返回的是float類型的數(shù)據(jù)。

② repeat函數(shù)
timeit模塊的repeat函數(shù)其實返回的是timeit模塊中Timer類repeat方法的執(zhí)行結(jié)果,repeat函數(shù)的源碼:

def repeat(stmt="pass", setup="pass", timer=default_timer,
           repeat=default_repeat, number=default_number, globals=None):
    """Convenience function to create Timer object and call repeat method."""
    return Timer(stmt, setup, timer, globals).repeat(repeat, number)

參數(shù):repeat函數(shù)比timeit函數(shù)多一個repeat參數(shù)

  • stmt:用來放需要進(jìn)行計算時間的代碼,可以接收字符串的表達(dá)式、單個變量、函數(shù)。
  • setup:可以用來傳stmt的環(huán)境,例如import和一些參數(shù)之類的。
  • number:執(zhí)行是的次數(shù),默認(rèn)是1000000
  • repeat:重復(fù)整個測試的個數(shù),默認(rèn)是3
  • 其它參數(shù)一般用不到,具體可查看文檔

返回值:

  • repeat函數(shù)返回的是列表類型的數(shù)據(jù)。

③ 測試列表推導(dǎo)式與for循環(huán)的執(zhí)行時間
使用timeit函數(shù):

import timeit

stmt_list = '''
lst=[]
for i in range(10000):
    lst.append(i)
'''
if __name__ == '__main__':
    print(timeit.timeit('[i for i in range(10000)]', number=10000))
    print(timeit.timeit(stmt_list, number=10000))
'''
3.346147895
5.789892938
'''

使用repeat函數(shù):

import timeit

stmt_list = '''
lst=[]
for i in range(10000):
    lst.append(i)
'''
if __name__ == '__main__':
    print(timeit.repeat('[i for i in range(10000)]', repeat=2, number=10000))
    print(timeit.repeat(stmt_list, repeat=2, number=10000))
'''
[3.374952514, 3.4277178010000005]
[5.748379824000001, 5.8717959529999995] 
'''
2.13 Random

隨機數(shù)是隨機試驗的結(jié)果,是計算機通過隨即種子根據(jù)一定算法計算出來的,隨機種子通常可以由系統(tǒng)時鐘產(chǎn)生。下面是random庫中基本方法:
① random()
產(chǎn)生一個0到1之間的隨機浮點數(shù):0<=n<1.0


在這里插入圖片描述

② randint(a,b)
產(chǎn)生指定范圍內(nèi)的整數(shù),a<=n<=b


在這里插入圖片描述

② uniform(a,b)
產(chǎn)生一個指定范圍內(nèi)的隨機浮點數(shù),a可以大于b,a>b時生成b<=n<=a;b>a時生成a<=n<=b
在這里插入圖片描述

④ randrange(a,b,step)

從按照指定,按指定基數(shù)(step)遞增的集合中獲取一個隨機數(shù)


在這里插入圖片描述

⑤ choice(sequence)
從序列中獲取一個隨機元素,sequence表示一個有序類型,泛指一系列類型,list、tuple字符串都屬于sequence
在這里插入圖片描述

⑥ shuffle(list)
將列表中的內(nèi)容打亂
在這里插入圖片描述

注意:不可以將suffle(list)賦值給另一list,輸出這個lis,是沒有意義的。原因是:suffle(list)只是修改list中內(nèi)容的順序
在這里插入圖片描述

⑦ sample(sequence,k)
從指定序列中獲取指定長度的片段,k是指定長度

⑧ 更多
可以通過dir(random)查看random庫中所有方法,另外可以使用help函數(shù)可以獲取操作方法的說明書,如:


在這里插入圖片描述
3. 第三方模塊
3.1 第三方模塊的安裝

① 包管理工具pip安裝

<kbd>pip install 模塊名</kbd>

② 源碼安裝

  • 下載源碼包(壓縮文件)
  • 加壓文件
  • 打開cmd,進(jìn)入文件目錄,執(zhí)行<kbd>python setup.py build</kbd>
  • 再執(zhí)行<kbd>python setup.py install</kbd>
3.2 jieba

① jieba模塊簡介

jieba是Python中一個重要的第三方分詞函數(shù)庫,能夠?qū)⒅形奈谋痉指畛芍形脑~語的序列。jieba原理是將中文文本與分詞詞庫對比,通過圖結(jié)構(gòu)和動態(tài)規(guī)劃算法找出最大概率的詞組。

② jieba模塊的三種分詞模式

  • 精確模式:將句子精確地分開,適合文本分析。
import jieba
str = '寧浩出任第22屆上海國際電影節(jié)亞洲新人獎評委會主席'
ls =jieba.lcut(str)
print(ls)

['寧浩', '出任', '第', '22', '屆', '上海', '國際', '電影節(jié)', '亞洲', '新人獎', '評委會', '主席']

  • 搜索引擎模式:在精確查找的基礎(chǔ)上對長詞再次切分,提高召回率,適合搜索引擎分詞。
import jieba
str = '寧浩出任第22屆上海國際電影節(jié)亞洲新人獎評委會主席'
ls =jieba.lcut_for_search(str)
print(ls)

['寧浩', '出任', '第', '22', '屆', '上海', '國際', '電影', '電影節(jié)', '亞洲', '新人', '新人獎', '評委', '委會', '評委會', '主席']

  • 全模式:把句子可以成詞的語句都掃描出來,速度快但不能解決歧義。
import jieba
str = '寧浩出任第22屆上海國際電影節(jié)亞洲新人獎評委會主席'
ls =jieba.lcut(str,cut_all=True)
print(ls)

['寧', '浩', '出任', '第', '22', '屆', '上海', '海國', '國際', '電影', '電影節(jié)', '亞洲', '新人', '新人獎', '獎評', '評委', '評委會', '委會', '會主', '主席']

3.3 pyInstaller

① 模塊概述
可以在Windows、Linux、Mac 0S等操作系統(tǒng)下將.py的Python源文件打包直接運行的可執(zhí)行文件。
② 模塊的優(yōu)點
通過對Python源文件打包,使Python程序在可以沒有安裝Python環(huán)境中運行,可作為獨立文件方便傳遞和管理。此外,公司通常是不開放自己源代碼的,將源文件打包成看不到源代碼的可執(zhí)行文件,安全性得到增強。
③ 模塊相關(guān)參數(shù)

<kbd>-F或--onefile</kbd>:在dist文件夾中只生成獨立的打包文件

<kbd>-h或--help</kbd>:幫助信息

<kbd>--clean</kbd>:清理打包過程中的臨時文件

<kbd>-i <圖標(biāo)文件路徑名.io></kbd>:指定打包程序使用的圖標(biāo)

<kbd>-D或--onedir</kbd>:默認(rèn)值,生成dist目錄

④ 模塊的使用

<kbd>$ pyinstaller -F test.py</kbd>

執(zhí)行完成后,源文件目錄生成dist和build目錄,build目錄是PyInstaller存儲臨時文件的目錄,可以完全刪除。最終打包程序在dist內(nèi)部與源文件同名的目錄中。

3.4 virtualenv

① 安裝virtualenv(安裝遇到問題可以在評論區(qū)留言)

<kbd>thanlon@thanlon-vivobook:~$ pip install virtualenv</kbd>

② 創(chuàng)建一個名字為venv名字的虛擬環(huán)境

<kbd>thanlon@thanlon-vivobook:~$ virtualenv venv</kbd>

③ 激活虛擬環(huán)境

<kbd></kbd>

⑤ 退出虛擬環(huán)境

⑥ 刪除虛擬環(huán)境


?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容