Python全棧開發武沛齊day06模組

lang333333發表於2024-03-11

day06 模組
今日概要:
環境搭建、基礎語法、資料型別、函式 -> 基本操作

模組,別人幫我們寫好的一大堆的功能程式碼。
模組:
- 自定義模組
- 功能簡單,一個py檔案就能實現功能。
- 功能多or負責,一個py檔案的功能拆分到多個py檔案

- 內建模組,Python內部已經攜帶。
  	import os
  	import re

- 第三方模組,網上下載  https://pypi.org/
	pip install xxx

1.知識回顧
• 環境搭建
- Python直譯器
C:\python39
- python.exe [直譯器]
- Scripts
- pip.exe
- pip3.exe
- pip3.9.exe [下載並安裝第三方模組]
- Lib
- re.py
- os.py
- site-packages
- openpyxl pip install openpyxl
- requests pip install requests

  • 命令列

    C:\python39\python.exe code.py
    C:\python39\Scripts\pip.exe install openpyxl

  • 環境變數 (預設)
    C:\python39\Scripts
    C:\python39\

    python code.py
    pip3.9 install openpyxl

  • IDE

    • Pycharm社群版 -> Pycharm專業版
      • 基礎語法

    • 編碼
      00000000 00000000 00000000 00000000
      ascii gbk unicode utf-8(*)
      關於中文:
      gbk -> 聯 -> 2個位元組 -> 00000000 00000000 -> 2的16次方
      b'\xc1\xaa'
      [193, 170]
      '11000001', '10101010'

      utf-8 -> 聯 -> 3個位元組 -> 00000000 00000000 00000000
      \xe8\x81\x94
      [232, 129, 148]
      '11101000 10000001 10010100'
      關於亂碼
      python直譯器編碼(Python讀取程式碼檔案時)

      • py3:utf-8編碼
      • py2:ascii編碼
  • 輸入輸出

  • 變數
    關鍵字:if else elif while break for continue def return

  • 條件語句
    if 值 :
    pass

  • 迴圈語句
    while for+range

  • 運算子

  • 字串格式化:% format f-string
    • 資料型別
    整型 int

    • 在py2中 int long ,在py3中只有int
    • 數字直接支援加減乘除 + 比較等
    • 特別的:8 * "x" -> "xxxxxxxx"

配置
print(f"{20 * ''}歡迎使用xx系統{20 * ''}")
- 除法
在py2中: 5/2 = 2 -> 5.0/2 = 2.5 5/2.0 =2.5
在py3中: 5/2 = 2.5
- 計算機本質上所有的內容都是二進位制01010101010
- 十進位制表示用整型 int("要轉換",base=2/8/10/16)
- 其他進位制 bin(十進位制整數) oct(十進位制整數) hex(十進位制整數)
布林型別 bool
- 常見的轉換False -> None 0 "" {} [] 空
- if while 等後面跟條件->轉換成布林值
while 10:
pass
if "root":
pass

字串 str
- 定義字串 "xxx" 'xxxx' """xxxx""" '''asdfadsf'''
- 獨有功能(方法),生成新的值,原來的值不會發生變化。
upper/lower/strip/replace/split/join/startswith...
- 公共功能
len、索引、切片、in包含、for迴圈+range
列表 list
- 定義列表
- 獨有功能(方法)
append/insert/clear/remove...
- 公共功能
len、索引、切片、in包含、for迴圈+range

字典 dict
- 獨有功能(方法)
items/values/keys/get
- 公共功能
len、鍵索引、in鍵包含、for迴圈+items/values/keys

- 通用知識點:解包
	name, age = ("武沛齊", 19)

	info = {"name": 'xx', "age": 19, 'email': "xxxx@xx.com"}

    for k, v in info.items():
        print(k, v)
    
    def get_info():
        # ....
        return [11, 22]

    ret,xx = get_info()
    print(ret,xx)

元組 tuple
v1 = (11,22,33,44)
v2 = (11,22,33,[88,99,77],123)
---------
v1 = (11,22,33,4)
v2 = (11) # 等價於 v2=11
v3 = (11,)
---------
v1 = [11,22,3,]
v2 = (11,22,33,44,)

浮點型 float
...
None
空值
函式預設返回值

v1 = [111,222,333]
v2 = v1.append(444) # append“函式”沒有返回值
print(v1) # [111,222,333,444]
print(v2) # None
------------
v10 = "root"
v11 = v10.upper()  # upper"函式"的返回值 大寫
print(v10)
print(v11) # ROOT

• 函式
- 基礎:定義、引數、返回值

  • 進階:

    • 預設引數如果是可變型別 [] {} 集合 內部元素可以被修改的型別

    • 作用域
      py:
      if 1==1:
      name = "武沛齊"
      print(name)

        for i in range(10):
        	pass
        print(i) # 9
      

      java:
      if(1==1){
      String name = "武沛齊";
      System.out.println(name);
      }

    • 閉包

    • 裝飾器 @+巢狀的函式=>不修改原函式內容的前提下,在函式的執行前後自定義操作

  • 內建函式
    sum/abs/hex/int/oct/bin/chr/ord/len/range/id/....
    open 檔案操作 r w a rb wb ab

  • 生成器函式

    • 表象:如果函式中出現了yield關鍵字,那麼這個函式就是生成器函式。
    • 意義:節省記憶體
      - 建立1~100000000 -> 直接在記憶體建立(佔用記憶體)
      - 建立1~100000000 -> 使用的過程中,邊使用變建立
      def info():
      v1 = 100
      v2 = 200
      return v1 + v2

ret = info()
print(ret)
# 1.生成器函式
def info():
v1 = 100
yield v1 + 10
v2 = 200
yield v2 + 10

return

2.執行生成器函式,不會執行函式內部的程式碼,而是直接返回一個 生成器物件

ret = info()

3.透過next+生成器物件,執行函式中的程式碼

for item in ret:
print(item)

value = next(ret)

print(value) # 110

value = next(ret)

print(value) # 210

value = next(ret) # 執行完畢後,報錯StopIteration

print(value) # 210

def my_range(limit):
i = 0
while i < limit:
    yield i
    i = i + 1

ret = my_range(20)

for item in ret:
print(item)

2.模組的概述
分類:
• 自定義模組
• 內建模組
• 第三方模組

2.1 自定義模組
模組:py檔案 + 資料夾+py檔案

2.1.1 基本使用
• 編寫程式碼
utils
- my.py
- encrypt.py
db.py
app.py [主程式]
• 匯入模組
import db
from utils import my
from utils import encrypt

db.?
my.?
encrypt.?

2.1.2 模組匯入的規則
在Python內部匯入模組時,必須要遵循他得規則,必須去指定的目錄中找py檔案。
import xxx
from xxx import ???
E:\PycharmProjects\crm
E:\PycharmProjects\crm
C:\Python39\python39.zip
C:\Python39\DLLs
C:\Python39\lib
C:\Python39
C:\Python39\lib\site-packages
尋找模組就是三個位置:
• 當前執行指令碼的同級目錄
• Python的安裝目錄 【內建模組】
• Python的安裝目錄+site-packages 【第三方模組】 pip install ?

問題1:同名

問題2:執行主程式
當前執行指令碼的同級目錄

問題3:pycharm自動新增sys.path

問題4:sys.path有關

2.1.3 主動新增sys.path
匯入模組時,都是根據sys.path中的目錄進行py檔案的尋找。

import os
import sys
base_dir = os.path.dirname(os.path.dirname(os.path.abspath(file)))
sys.path.append(base_dir)

import db

2.1.4 相對匯入和絕對匯入
import db
import utils.my
import utils.encrypt
from utils import my
from utils import encrypt

一般情況下:
• 主程式匯入其他模組時,一般都是絕對匯入。
• 在資料夾內,又要匯入自己資料夾內的一些其他的py檔案,可以使用【絕對】+【相對】
不相關的模組 【絕對】
先關的模組 【相對】

2.1.5 主檔案和__name__
• 主檔案:啟動的程式
def run():
pass

run()
def run():
pass

if name == "main":
run()
• __name__是什麼?
name
- 當執行的時當前py檔案,等於 main
- 如果當前模式是被匯入的話,則等於模組的名字。

一般情況下,一個只有一個執行的入口【主檔案】


模組的測試,有時候也會出現 __name__的機制。

2.1.6 衝突 & 成員
import db as d1
from utils.net import db as d2

def run():
d1.f1()
d1.f2()
d2.xxx()

if name == 'main':
run()

小結
• 模組,本質就是一個py檔案或資料夾。
• 匯入模組根據 sys.path 路徑尋找相關名稱。
指令碼的所有目錄
安裝目錄
安裝目錄/site-packages
• 主動新增
import sys
sys.path.append("....")
• pycharm自動將專案根目錄新增到sys.path
• 匯入
import xxxx
from xxxx import xxxxxx
• 主檔案
def run():
pass

if name == 'main':
run()
• 衝突命名
from xxx import xxx as xxxxx
• 成員
from xxx import x,x,x,x,x
• 注意事項:千萬不要讓自己建立的py檔案與內建模組同名。
random/re/datetime/xml/configparse/....

2.2 內建模組
Python直譯器內部攜帶的模組py + 函式。

2.2.1 random
import random

1.隨機整數

v1 = random.randint(10, 20)
print(v1)

2.隨機小數

v1 = random.uniform(10, 20)
print(v1)

3.隨機選擇

v1 = random.choice([11, 22, 33, 44, 55])
print(v1)

4.隨機選擇

v1 = random.sample([11, 22, 33, 44, 55], 2)
print(v1)

5.打亂順序

num_list = [11, 22, 33, 44, 55]
print(num_list)
random.shuffle(num_list)
print(num_list)

案例
• 根據工號生成公司的員工資訊,放到列表中
import random

user_list = []

for i in range(1, 301):
user_list.append(f"工號-{i}")

lucky_user = random.choice(user_list)
print(lucky_user)
• 隨機獲取3個員工
import random

user_list = []

for i in range(1, 301):
user_list.append(f"工號-{i}")

lucky_list = random.sample(user_list,3)
print(lucky_list)
• 讀取檔案中的名字並進行隨機抽取

import random

user_list = []

with open('db.txt', mode='r', encoding='utf-8') as f:
for line in f:
line = line.strip()
if line:
user_list.append(line)

lucky_list = random.sample(user_list, 3)
print(lucky_list)

import os

import random

user_list = []

for file_name in os.listdir("files"):
depart_name = file_name.split(".")[0]
file_path = os.path.join("files", file_name)
f = open(file_path, mode='r', encoding='utf-8')
for line in f:
line = line.strip()
if line:
user_list.append(f"{depart_name}-{line}")
f.close()

print(user_list)

ret = random.sample(user_list, 3)
print(ret)

• 年會抽獎案例
- 各部門統計部門員工的姓名 => 部門名稱.txt

  • 讀取使用者資訊

  • 根據特定的獎項配置來進行抽獎
    data_list = [
    ("三等獎", 5 ,"空氣清淨機"),
    ("二等獎", 3 ,"ipad"),
    ("一等獎", 2 ,"iphone13"),
    ("特等獎", 1 ,"寶馬x5"),
    ]

  • 一個一個獎項去抽取,每次抽取後領導講話,再繼續抽取

    input("回車繼續")
    print("123")
    while True:
    text = input("輸入q繼續")
    if text == 'q':
    break
    import os
    import random

print(f"{30 * ''}聯通年會抽獎系統{30 * ''}")

1.讀取所有員工資訊

user_list = []
for file_name in os.listdir("files"):
depart_name = file_name.split(".")[0]
file_path = os.path.join("files", file_name)
f = open(file_path, mode='r', encoding='utf-8')
for line in f:
line = line.strip()
if line:
user_list.append(f"{depart_name}-{line}")
f.close()

info = f"""員工:{len(user_list)}
時間:2024-01-01
"""
print(info)

2.輸入特定字元繼續

while True:
text = input("輸入y/Y繼續:").strip()
if text.upper() == "Y":
break

3.獎項資訊

print(f"{30 * '-'}獎品資訊{30 * '-'}")
data_list = [
("三等獎", 5, "空氣清淨機"),
("二等獎", 3, "ipad"),
("一等獎", 2, "iphone13"),
("特等獎", 1, "寶馬x5"),
]
for text, count, title in data_list:
print(f"{text},有{count}個,獎品是:{title}")

4.輸入特定字元繼續

while True:
text = input("輸入y/Y繼續:").strip()
if text.upper() == "Y":
break

5.開始去抽獎

print(f"{30 * '-'}開始抽獎{30 * '-'}")
for text, count, title in data_list:
lucky_list = random.sample(user_list, count)
for name in lucky_list:
user_list.remove(name)
print(f"{text},中獎人員:{lucky_list},獎品:{title}")
# 1.全部都出來; 2.有人重複獲獎
input("")

import os

import random

def get_user_list():
user_list = []
for file_name in os.listdir("files"):
depart_name = file_name.split(".")[0]
file_path = os.path.join("files", file_name)
f = open(file_path, mode='r', encoding='utf-8')
for line in f:
line = line.strip()
if line:
user_list.append(f"{depart_name}-{line}")
f.close()
return user_list

def while_user_input():
while True:
text = input("輸入y/Y繼續:").strip()
if text.upper() == "Y":
return

def choose_lucky(data_list, user_list):
for text, count, title in data_list:
lucky_list = random.sample(user_list, count)
for name in lucky_list:
user_list.remove(name)
print(f"{text},中獎人員:{lucky_list},獎品:{title}")
# 1.全部都出來; 2.有人重複獲獎
input("")

def run():
print(f"{30 * ''}聯通年會抽獎系統{30 * ''}")

# 1.讀取所有員工資訊
user_list = get_user_list()
info = f"員工:{len(user_list)}\n時間:2024-01-01\n"
print(info)

# 2.輸入特定字元繼續
while_user_input()

# 3.獎項資訊
print(f"{30 * '-'}獎品資訊{30 * '-'}")
data_list = [
    ("三等獎", 5, "空氣清淨機"),
    ("二等獎", 3, "ipad"),
    ("一等獎", 2, "iphone13"),
    ("特等獎", 1, "寶馬x5"),
]
for text, count, title in data_list:
    print(f"{text},有{count}個,獎品是:{title}")

# 4.輸入特定字元繼續
while_user_input()

# 5.開始去抽獎
print(f"{30 * '-'}開始抽獎{30 * '-'}")
choose_lucky(data_list, user_list)

if name == 'main':
run()
把程序導向程式設計函式實現時:可讀性 + 重用性

2.2.2 hashlib
此模組用於實現加密,例如:md5加密
import hashlib

data = "中國聯通"

obj = hashlib.md5()
obj.update( data.encode('utf-8') )
ret = obj.hexdigest()

print(ret) # 密文 6a883ea3dac8ff60006aad7da941e2d7

為什麼要加密?
wupeiqi,123
alex,123
eric,123123
wupeiqi,6a883ea3dac8ff60006aad7da941e2d7
alex,6a883ea3dac8ff60006aad7da941e2d7
eric,6a883ea3dac8ff60006aad7da941e2d7
md5的密文是無法反解。

撞庫
將常見的密碼計算出他得md5值,儲存起來
123 6a883ea3dac8ff60006aad7da941e2d7
123 6a883ea3dac8ff60006aad7da941e2d7
123 6a883ea3dac8ff60006aad7da941e2d7

加密+加鹽(加入一些更加隨機的字串)
import hashlib

data = "admin"

obj = hashlib.md5("asdf9uknjakndf9u7jkla;sdkjf".encode('utf-8'))
obj.update(data.encode('utf-8'))
ret = obj.hexdigest()

print(ret) # 密文

問題:無法反解,我們知道明文嗎?
• 使用者註冊
import hashlib

1.使用者輸入

user = input("使用者名稱:")
pwd = input("密碼:")

2.加密

obj = hashlib.md5("asdf9uknjakndf9u7jkla;sdkjf".encode('utf-8'))
obj.update(pwd.encode('utf-8'))
encrypt_pwd = obj.hexdigest()

3.寫入檔案

with open("user.txt",mode='a',encoding='utf-8') as f:
f.write(f"{user},{encrypt_pwd}\n")
wupeiqi,825c24c5627fd5b70f1efdea26335f3e 123
eric,606d3cc3f169ed9536573a589eb8c08f 798
• 使用者登入
import hashlib

1.使用者輸入

user = input("使用者名稱:")
pwd = input("密碼:")

2.加密

obj = hashlib.md5("asdf9uknjakndf9u7jkla;sdkjf".encode('utf-8'))
obj.update(pwd.encode('utf-8'))
encrypt_pwd = obj.hexdigest()

3.讀取檔案 + 進行密文的比較(簡單)

is_success = False
with open('user.txt', mode='r', encoding='utf-8') as f:
for line in f:
line = line.strip()
if not line:
continue
old_user, old_pwd = line.split(",")
if old_user == user and old_pwd == encrypt_pwd:
is_success = True
break

if is_success:
print("登入成功")
else:
print("登入失敗")

方法二
import hashlib

1.使用者輸入

user = input("使用者名稱:")
pwd = input("密碼:")

2.加密

obj = hashlib.md5("asdf9uknjakndf9u7jkla;sdkjf".encode('utf-8'))
obj.update(pwd.encode('utf-8'))
encrypt_pwd = obj.hexdigest()

3.讀取檔案 + 構造使用者字典

user_dict = {}
with open('user.txt', mode='r', encoding='utf-8') as f:
for line in f:
line = line.strip()
if not line:
continue
old_user, old_pwd = line.split(",")
user_dict[old_user] = old_pwd

4.比較

db_pwd = user_dict.get(user)
if db_pwd == encrypt_pwd:
print("登入成功")
else:
print("登入失敗")
方法三:函式實現
import hashlib

SALT = "asdf9uknjakndf9u7jkla;sdkjf"

def md5(data_string):
obj = hashlib.md5(SALT.encode('utf-8'))
obj.update(data_string.encode('utf-8'))
return obj.hexdigest()

def get_user_info():
user_dict = {}
with open('user.txt', mode='r', encoding='utf-8') as f:
for line in f:
line = line.strip()
if not line:
continue
old_user, old_pwd = line.split(",")
user_dict[old_user] = old_pwd
return user_dict

def run():
# 1.使用者輸入
user = input("使用者名稱:")
pwd = input("密碼:")

# 2.加密
encrypt_pwd = md5(pwd)

# 3.讀取檔案 + 構造使用者字典
user_dict = get_user_info()

# 4.比較
db_pwd = user_dict.get(user)
if db_pwd == encrypt_pwd:
    print("登入成功")
else:
    print("登入失敗")

if name == 'main':
run()
- 建議結構

  • 全域性變數一定要大寫,區域性變數是小寫
  • not,取反

2.2.3 json

1.基本操作
json:本質上是一個特定結構的字串。
意義:打通不同程式語言之間進行相互通訊時的資料格式問題。

• 序列化(Python資料型別 -> JSON格式字串) 【網站,給別人提供資訊】
info = {"code":1000,"message":"success","num":[11,22,33]}

import json
data_string = json.dumps(info)
print(data_string)

'{"code": 1000, "message": "success", "num": [11, 22, 33]}'

• 反序列化(JSON格式字串->Python資料型別)【爬蟲,網路獲取其他使用者資訊】
data_string = '{"code": 1000, "message": "success", "num": [11, 22, 33]}'

import json
data_dict = json.loads(data_string)
print(data_dict)
print(data_dict["num"])

案例:爬蟲【反序列化】
網路獲取平臺資訊,讀取資訊。
pip3.9 install requests
Windows PowerShell改成cmd
Settings,Tools,Terminal,改成cmd.exe

import requests
import json

res = requests.get(
url="https://movie.douban.com/j/search_subjects?type=movie&tag=熱門&sort=recommend&page_limit=20&page_start=20",
headers={
"user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36"
}
)

反序列化,將json字串轉換成Python的資料型別

data_dict = json.loads(res.text)

for row in data_dict['subjects']:
print(f"電影:{row['title']} 評分:{row['rate']} 網址:{row['url']}")

import requests
import json

res = requests.get(
url="https://api.luffycity.com/api/v1/course/actual/?limit=12&offset=0&category_id=recommend",
headers={
"user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36"
}
)

print(res.text)

data_dict = json.loads(res.text)

print(data_dict)

for row in data_dict['data']['result']:
print(row['name'])

案例:API服務【序列化】
提供API給 小程式/手機APP 等提供資料。
pip3.9 install flask

from flask import Flask

app = Flask(name)

@app.route("/index")
def index():
info = {"code": 1000, "message": "success", "num": [11, 22, 33]}
import json

return json.dumps(info)

if name == 'main':
app.run()

2.中文
info = {"code": 1000, "message": "成功", "num": [11, 22, 33]}

import json

ret = json.dumps(info,ensure_ascii=False)
print(ret)

3.Python支援序列化型別
+-------------------+---------------+
| Python | JSON |
+=====+=+
| dict | object |
+-------------------+---------------+
| list, tuple | array |
+-------------------+---------------+
| str | string |
+-------------------+---------------+
| int, float | number |
+-------------------+---------------+
| True | true |
+-------------------+---------------+
| False | false |
+-------------------+---------------+
| None | null |
+-------------------+---------------+
Python JSON字串
{"k1":123,"k2":456}
{'k1':123,'k2':456} {"k1":123,"k2":456}
[11,22,33]
(11,22,33) [11,22,33]
[True,False,None] [true,false,null]

案例
• 判斷以下型別那個是JSON格式字串
" {"k1":123,"k2":456} "
" {'k1':123,"k2":456} "
• 判斷以下那個是Python的資料型別?
v1 = {"k1":123,"k2":456}
v2 = {'k1':123,"k2":456}
• 注意
單引號和雙引號 JSON只有雙引號
元組+列表 陣列=列表
[True,False,None]

4.檔案
import json

info = {"code": 1000, "message": "成功", "num": [11, 22, 33]}
data_string = json.dumps()
print(data_string)
import json

data_string = '{"code": 1000, "message": "success", "num": [11, 22, 33]}'
data_dict = json.loads(data_string)
print(data_dict)

• 序列化
import json
info = {"code": 1000, "message": "成功", "num": [11, 22, 33]}

with open("info.json", mode='w', encoding="utf-8") as f:
json.dump(info, f,ensure_ascii=False)
• 反序列化
import json

with open("info.json", mode='r', encoding="utf-8") as f:
data_dict = json.load(f)
print(data_dict, type(data_dict))

5.縮排檢視
import json

info = {"code": 1000, "message": "成功", "num": [11, 22, 33]}

res = json.dumps(info,ensure_ascii=False,indent=4)

print(res)

with open("info.json", mode='w', encoding="utf-8") as f:
json.dump(info, f,ensure_ascii=False,indent=4)

2.2.4 時間相關
• time
• datetime

1.time
import time

1.獲取時間戳(自1970年1月1日)

v1 = time.time()

2.主動停止

while True:
time.sleep(1)
print(123)

2.datetime
• 時間戳,獲取時間差,獲取隨機數,
import time

v1 = time.time() # 1683190068.0479393
• 字串格式,寫入檔案+網路傳輸
v1 = "2023年10月19號 15:33"
v2 = "2023-10-19"
• datetime格式,時間的加減
import datetime

v1 = datetime.datetime.now() # 物件

相關轉換:

• 字串 -> datetime型別
text = "2023-05-02"

from datetime import datetime

res = datetime.strptime(text,"%Y-%m-%d")
print(res, type(res))

• datetime型別 -> 字串
from datetime import datetime

res = datetime.now()

date_string = res.strftime("%Y-%m-%d")
print(date_string, type(date_string))

• 時間戳 -> datetime型別
from datetime import datetime
import time

v1 = time.time()

res = datetime.fromtimestamp(v1)
print(res,type(res))

• datetime型別->時間戳
from datetime import datetime

res = datetime.now()

result = res.timestamp()
print(result)

案例:使用者註冊
from datetime import datetime

user = input("使用者名稱:")
pwd = input("密碼:")
date_string = datetime.now().strftime("%Y-%m-%d")

with open("db.txt", mode='a', encoding='utf-8') as f:
f.write(f"{user},{pwd},{date_string}\n")

案例:使用者註冊 + 檔案拆分
2023-05-03.txt
2023-05-04.txt
from datetime import datetime

user = input("使用者名稱:")
pwd = input("密碼:")
date_string = datetime.now().strftime("%Y-%m-%d")

with open(f"{date_string}.txt", mode='a', encoding='utf-8') as f:
f.write(f"{user},{pwd},{date_string}\n")

案例:考勤處理
from datetime import datetime

v1 = "2023-05-04 09:01:11"
start_date = datetime.strptime(v1, "%Y-%m-%d %H:%M:%S")

v2 = "2023-05-04 19:11:01"
end_date = datetime.strptime(v2, "%Y-%m-%d %H:%M:%S")

interval = end_date - start_date

print(interval.seconds)
print(60 * 60 * 8)

from datetime import datetime,timedelta

ctime = datetime.now()

value = ctime + timedelta(hours=36,minutes=10,seconds=10)

print(value) # datetime

from datetime import datetime

1.讀取檔案

2.構造字典

user_dict = {}
with open("dingding.txt", mode='r', encoding='utf-8') as f:
for line in f:
line = line.strip()
if not line:
continue
name, date_string = line.split(",")
if name in user_dict:
user_dict[name].append(date_string)
else:
user_dict[name] = [date_string]

print(user_dict)

3.統計考勤

for name, history in user_dict.items():
# print(name, history)
if len(history) < 2:
print(name, "缺少開啟記錄")
continue
start_date = datetime.strptime(history[0], "%Y-%m-%d %H:%M:%S")
end_date = datetime.strptime(history[-1], "%Y-%m-%d %H:%M:%S")

interval = end_date - start_date

if interval.seconds >= (8 * 60 * 60):
    print(name, "正常考勤")
else:
    print(name, "異常考勤")

2.2.5 os
• 路徑的拼接
import os

path = os.path.join("db","demo",'xxx.txt')
print(path) # db/demo/xxx.txt mac
print(path) # db\demo\xxx.txt win
• 路徑的上級目錄
import os

path = os.path.join("db", "demo", 'xxx.txt')
print(path) # db\demo\xxx.txt

result = os.path.dirname(path)
print(result) # db\demo
• 檔案的絕對路徑
import os

path = os.path.abspath("db.txt")
print(path) # E:\PycharmProjects\LearnPython\006\db.txt
import os

path = os.path.abspath("xxxxxxx.txt")
print(path) # E:\PycharmProjects\LearnPython\006\xxxxxxx.txt
import os

abs_path = os.path.abspath(file)
print(abs_path)
# 應用場景:獲取當前專案的根目錄

import os
BASE_DIR = os.path.dirname(os.path.abspath(file))
print(BASE_DIR)
import os

BASE_DIR = os.path.dirname(os.path.abspath(file))

file_path = os.path.join(BASE_DIR, 'db.txt')
print(file_path)

file_path = os.path.join(BASE_DIR, 'files', '運維部.txt')
print(file_path)
– 絕對路徑讀取檔案 【絕對路徑】【推薦】
import os

BASE_DIR = os.path.dirname(os.path.abspath(file))

file_path = os.path.join(BASE_DIR, 'db.txt')

with open(file_path,mode='r',encoding='utf-8') as f:
data = f.read()
print(data)
– 相對路徑讀取檔案【當前所在目錄有關係】
with open("db.txt", mode='r', encoding='utf-8') as f:
data = f.read()
print(data)

相關文章