Python全栈开发武沛齐day06模块

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)

posted @ 2024-03-11 22:02  lang333333  阅读(105)  评论(0)    收藏  举报