首页 > 编程语言 >python基础-函数与模块1

python基础-函数与模块1

时间:2023-10-20 16:57:22浏览次数:44  
标签:files f1 sheet 函数 文件 python 模块 print wb

目录

了解函数和模块

  • 函数:一个用于专门实现某个功能的代码块,可复用
    • 内置函数
len,bin,oct,hex...
  • 自定义函数
def send_email():
    # xxx
    pass

send_emaill()
  • 模块:集成了很多模块功能的函数集合
    • 内置模块:python内部提供
import random

num1 = random.randrange(19)  # 0-19
num2 = random.randint(1, 19)  # 1-19
num3 = round(random.random(), 3)  # 随机浮点数,保留小数点后三位
print(num1, num2, num3)
  • 自定义模块:
# 创建一个msg.py文件
def send_email():
    pass

def send_wechat():
    pass

# 导入msg模块
import msg
msg.send_wechat()
  • 第三方模块:下载别人写好的模块(功能集合)
pip install xxx

1. 文件操作

  • 字符串类型(str):在程序中用于表示文字信息,本质是unicode编码的二进制
name = "小明"
  • 字节类型(bytes)
    • 可表示文字信息,本质是utf-8/gbk等编码的二进制(对unicode进行压缩,方便文件存储和数据传输)
name = "小明"
data = name.encode('utf-8')
print(data)  # b'\xe9\x82\xb5\xe5\x86\xb2'

result = data.decode('utf-8')
print(result)  # "小明"
  • 可表示原始二进制(图片、文件等信息)

1.1 读文件

  • 读文本文件
    • Windows写绝对路径 :open(r'C:\Users\chong\Desktop\Typore\Python')
    • 读文件文件不存在会报错
import os

if os.path.exists('files/info.txt'):
    file_object = open('files/info.txt', mode='rb')  # 1. 打开文件,rb:读取文件原始的二进制(r读 read,b二进制 binary)
    data = file_object.read()  # 2. 读取文件的内容,并赋值给data
    file_object.close()  # 3. 关闭文件
print(data.decode('utf-8'))  # 4. 输出data变量


1.2 写文件

  • 写文本文件
    • 写文件不存在会直接创建这个文件
    • w 打开文件时,会先清空,再处理
    • 读文件时是二进制,打开内容时默认是二进制,写文件内容是二进制
    • 如果写入的是字符串类型需要先把字符串转换为二进制
file_object = open('files/info.txt', mode='wb')  # 1. 打开文件,w写,b要求写入的文件需要是字节类型
file_object.write('hello')  # 2. 将字符串转换为二进制写入,也可以 mode='wt',encoding='utf-8'
file_object.close()  # 3. 关闭文件
  • 写图片、视频等文件
f1 = open('files/image1.jpg', mode='rb')
content = f1.read()
f1.close()

f2 = open('files/image2.jpg', mode='wb')
f2.write(content)
f2.close

练习

# 1. 输入多个用户名密码,保存到一个文件
# mode='at'  # 下次写不清空
f1 = open("files/userfile.txt", mode='wt', encoding='utf-8')
while True:
    user = input("请输入用户名 (Q/q退出):")
    if user.upper() == "Q":
        break
    pwd = input("请输入密码:")
    data = "用户名:{}  密码{}\n".format(user, pwd)
    f1.write(data)
f1.close()

# 2. 去网上下载文件并保存
"""
利用Python向某个网址发送请求并获取结果(利用第三方模块)
import requests
request.get(url="网址")
"""
import requests

result = requests.get(
    url="https://movie.douban.com/j/search_subjects?type=movie&tag=%E7%83%AD%E9%97%A8&sort=recommend&page_limit=20&page_start=20",
    headers={
        'User-Agent': 'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.71 Safari/537.36'
}
)
f1 = open("files/content.txt", mode='wb')
f1.write(result.content)
f1.close()

# 3. 网上下载一个图片,保存到本地
import requests

url = 'http://tenfei05.cfp.cn/creative/vcg/veer/1600water/veer-305061729.jpg'
headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.71 Safari/537.36'}
res = requests.get(url, headers=headers)

with open('files/a.jpg', mode='wb') as f:
    f.write(res.content)

1.3 文件打开模式

  • t:文本模式-默认
  • 只读:rrtrb
    • 存在,读
    • 不存在,报错
  • 只写:wwtwb
    • 存在,清空再写
    • 不存在,创建再写
  • 只写:xxtxb
    • 存在,报错
    • 不存在,创建再写
  • 只写:aatab
    • 存在,尾部追加
    • 不存在,创建再写
  • 读写
    • r+rt+rb+      默认光标位置:起始位置
# 先读再写从末尾开始
# 先读文件 从初始位置开始读,读完光标会在末尾位置,此时再去写文件会在末尾开始写

# 先写再读从光标位置开始覆盖
# 默认打开文件光标在起始位置,如果直接写会在光标位置开始写,会把起始位置的内容覆盖,此时再去读文件的话,会从覆盖位置的末尾至文本的末尾
f1 = open('files/info.txt', mode='rt+', encoding='utf-8')

# 读取内容
data = f1.read()
print(data)

# 写入内容
f1.write("你好呀")
f1.close()
  • w+wt+wb+      默认光标位置:起始位置 (清空文件)
# 读到的永远是空
# 可通过 f1.seek(0) 将读取光标位置重置到起始,再去读文件,读到的每次都是所有内容
f1 = open('files/info.txt', mode='wt+', encoding='utf-8')

# 写入内容
f1.write("heiheihei")
f1.write("xixixi")

# 将光标重置值起始 再去读取内容
f1.seek(0)
data = f1.read()
print(data)

# 关闭文件
f1.close()
  • x+xt+xb+      默认光标位置:起始位置 (新文件)  # 不常用忽略
  • a+at+ab+      默认光标位置:末尾
# 默认打开位置在光标最后
# 读到的永远是空
# 可通过 f1.seek(0) 将读取光标位置重置到起始,再去读文件
# 在 a 模式下调用 write 在文件中写入内容时,永远只能将内容写到尾部,不会写到光标的位置

1.4 常见功能

  • 在ASCII码编码方案中,一个英文字符占用一个字节,一个汉字字符占用两个字节的空间
  • 在Unicode编码方案中,一个英文字符或一个汉字字符都占用两个字节的空间
  • 在UTF-8编码方案中,一个英文字符占用一个字节,一个汉字字符占用三个字节的空间

读文件操作

  • read:读所有
# 读文本格式(默认)
f1 = open('files/info.txt', mode='rt', encoding='utf-8')
data = f1.read()
f1.close()

# 读二进制格式
f1 = open('files/info.txt', mode='rb')
data = f1.read()
f1.close()
  • read:读n个字符 or 字节
# 读文本格式
f1 = open('files/info.txt', mode='r', encoding='utf-8')
data = f1.read(1)  # 读取一个字符 邵
f1.close()

# 读二进制格式
f1 = open('files/info.txt', mode='rb')
data = f1.read(1)  # 读取一个字节 b'\xe9' 
f1.close()
  • redline:读一行、next() 跳过一行
# 读文本格式
f1 = open('info.txt', mode='r', encoding='utf-8')
v1 = f1.readline().strip()  # line1
next(f1)  # 跳过一行
v2 = f1.readline().strip()  # line3
f1.readline()  #  跳过一行
v3 = f1.readline().strip()  # line5
f1.close()
print(v1, v2, v3)

# for 逐行读取
f1 = open('files/info.txt', mode='r', encoding='utf-8')
for line in f1:
    # print(line,end="")
    print(line.strip())
f1.close()
  • readlines:读所有行 ,得到的是一个列表
f1 = open('files/info.txt', mode='r', encoding='utf-8')
v1 = f1.readlines()  # ['line1\n', 'line2\n', 'line3']
# f.readline().splitlines():去掉读文件时空出来的一行
f1.close()

写文件操作

  • write
f = open('files/info.txt', mode='a', encoding='utf-8')  # 以字符串的格式打开
f.write("hello")  # 以字符串的格式写入
f.close()

f = open('files/info.txt', mode='ab')  # 以字节的格式打开
f.write("world".encode("utf-8"))  # 字节转字符串格式写入
f.close
  • flush 刷到硬盘
f = open('files/info.txt', mode='a', encoding='utf-8')
count = 0
while True:
    f.write("hello")  # 不是写到了硬盘,而是写在缓冲区,系统会将缓冲区的内容刷到硬盘
    f.flush()  # flush 立即刷到硬盘
    count += 1
    if count == 20:
        break
f.close()
  • seek 移动光标位置
    • 注意: 在 a 模式下调用 write 在文件中写入内容时,永远只能将内容写到尾部,不会写到光标的位置
      a 模式使用 write,用于都是先将光标移动到最后,再写数据
# 假设info.txt的文本内容是 "你好呀中国"

f1 = open('files/info.txt', mode='r+', encoding='utf-8')
f1.seek(3)  # 移动到指定字节位置
f1.write("我")  # 光标移动三个字节 "你我呀中国"
f1.close()

  • tell 获取光标当前位置
f1 = open('files/info.txt', mode='r', encoding='utf-8')
f1.read(3)  # 读三个字符
p1 = f1.tell()  # 9 
f1.close()

f1 = open('files/info.txt', mode='rb')
f1.read(3)  # 读三个字节
p1 = f1.tell()  # 3  
f1.close()

1.5 文件上下文管理

  • 直接使用 open 方式操作文件每次都要打开和关闭文件,比较繁琐
  • 使用 with上下文管理,可以自动实现关闭文件
with open('files/info.txt', mode='rt', encoding='utf-8') as f1:
    data = f1.read()
    print(data)
# python2.7以后,with支持对多个文件的上下文进行管理
with open('info.txt', mode='rt', encoding='utf-8') as f1, open('xx', mode='rt') as f2:
    data = f1.read()
    data = f2.read()
    print(data)
    ...


练习题

  1. 补充代码,实现下载视频并保存到本地
import requests

res = requests.get(
    url="https://aweme.snssdk.com/aweme/v1/playwm/?video_id=v0d00fb60000bvi0ba63vni5gqts0uag&ratio=720p&line=0",
    headers={
        "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36"
    }
)

# 补充代码
with open('files/nba.mp4', mode='wb') as video_file:
    video_file.write(res.content)
  1. 日志分析,计算所有用户的访问次数,并写入files/sum_ip.txt,日志如下:files/access.log

access.log

"""
111.196.244.192 - - [27/Jan/2021:16:47:27 +0800] "GET /aa HTTP/1.1" 404 555 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.66 Safari/537.36" "-" "-"
...
"""

import json

ip_dict = {}
with open('files/info.txt') as f1, open('files/sum_ip.txt', mode='wt') as f2:
    for line in f1:
        ip = line.split(' ')[0]
        if ip not in ip_dict:
            ip_dict[ip] = 1
        else:
            ip_dict[ip] += 1
    f2.write(json.dumps(ip_dict))
  1. 筛选出股票 当前价大于20 的所有股票信息
"""
股票代码,股票名称,当前价,涨跌额,涨跌幅
SH601778,中国晶科,6.29,+1.92,+43.94%
SH688566,吉贝尔,52.66,+6.96,+15.24%
SH688268,华特气体,88.80,+11.72,+15.20%
SH600734,实达集团,2.60,+0.24,+10.17%
"""
with open('files/stock.txt', mode='rt', encoding='utf-8') as stockfile:
    # 跳过第一行
    stockfile.readline()
    # 继续往下读
    for line in stockfile:
        price = float(line.split(",")[2])
        if price > 20:
            print(line.strip())
  1. 修改文件内容
"""
- 文件读到内存,再通过replace (适用于小文件,不适用大文件)
- 逐行读取文件内容,遇到关键词做替换 (此方法不可取,关键词长度与替换长度可能不同,有光标问题)
- 同时打开两文件,读 + 写 (大文件加小文件都适用)
"""
import os
import shutil

with open('files/access.log', mode='rt', encoding='utf-8') as f1, open('files/new.log', mode='w',
                                                                       encoding='utf-8') as f2:
    for line in f1:
        new_line = line.replace("404", "200")
        f2.write(new_line)

# 重命名 os方式 & shutil方式
os.rename('files/new.log', 'files/access2.log')
# shutil.move("files/new.log", "files/access2.log")  # 重命名文件,如果文件名存在会覆盖掉

2. csv文件

逗号分隔值 (Comma-Separated Valuses,CSV,有时也称为字符分隔值,因为分隔符也可以不是逗号),其文件以纯文本形式存储表格数据(数字和文本),对于这种格式的数据,我们需要利用open函数来读取文件并根据逗号分割的特点来进行处理

股票代码,股票名称,当前价,涨跌额,涨跌幅
SH601778,中国晶科,6.29,+1.92,+43.94%
SH688566,吉贝尔,52.66,+6.96,+15.24%
...

练习题:下载文档的所有图片且以用户名为图片名称存储:
info.csv

"""
ID,用户名,头像
26044585,Hush,https://hbimg.huabanimg.com/51d46dc32abe7ac7f83b94c67bb88cacc46869954f478-aP4Q3V
...
"""

import os
import requests

with open('info.csv', mode='r', encoding='gbk') as f1:
    # 跳过第一行表头
    next(f1)
    for line in f1:
        user_id, username, url = line.replace('"', '').strip().split(",")
        # 根据URL下载图片
        result = requests.get(
            url=url,
            headers={
                "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36"
            }
        )
        # 将图片的内容写入到文件
        if not os.path.exists('files/images'):
            os.makedirs('files/images')
        with open("files/images/{}.png".format(user_id), mode='wb') as image:
            print("下载: files/{}.png".format(user_id))
            image.write(result.content)

3. ini文件


ini文件一般用于存储服务的配置文件。例如:mysql的配置文件 my.ini

[mysqld]
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
log-bin=py-mysql-bin
character-set-server=utf8
collation-server=utf8_general_ci
log-error=/var/log/mysqld.log
# Disabling symbolic-links is recommended to prevent assorted security risks
symbolic-links=0

[mysqld_safe]
log-error=/var/log/mariadb/mariadb.log
pid-file=/var/run/mariadb/mariadb.pid

[client]
default-character-set=utf8

这种格式是可以直接使用open读取,考虑处理比较麻烦,所以python提供了更为方便的方式

  • 获取所有节点
import configparser

config = configparser.ConfigParser()
config.read('files/my.cnf', encoding='utf-8')

result = config.sections()  # 截取所有节点生产一个列表
print(result)  # ['mysqld', 'mysqld_safe', 'client']
  • 获取某个节点下的键值
import configparser

config = configparser.ConfigParser()
config.read('files/my.cnf', encoding='utf-8')

result = config.items("mysqld_safe")  # 截取单个节点的所有键,列表套元组格式
print(result)  # [('log-error', '/var/log/mariadb/mariadb.log'), ('pid-file', '/var/run/mariadb/mariadb.pid')]

for key, value in config.items("mysqld_safe"):
    print(key, value)
  • 获取某个节点下的键对应的值
import configparser
config = configparser.ConfigParser()
config.read('files/my.cnf',encoding='utf-8')

result = config.get("mysqld","log-error")
print(result)
  • 其他功能
import configparser

config = configparser.ConfigParser()
config.read('files/my.cnf', encoding='utf-8')

# 判断某个节点是否存在
v1 = config.has_section("client")  # True

# 添加一个节点,放到内存中,再写入文件 (需要节点不存在)
config.add_section("group")  # 添加一个group节点
config.write(open('files/new.cnf', mode='w', encoding='utf-8'))  # 写到其它文件,也可以填写在当前文件

# 在节点中添加键值(内容),需要节点存在
config.set('group', 'id', "1000")  # 在group节点中添加键值id = 1000
config.write(open('files/new.cnf', mode='w', encoding='utf-8'))

# 删除节点下的键值
config.remove_option('group', 'id')  # 删除group节点下的id键 
config.write(open('files/new.cnf', mode='w', encoding='utf-8'))

# 删除节点
config.remove_section('group')  # 删除client节点
config.write(open('files/new.cnf', mode='w', encoding='utf-8'))

4. xml文件

可扩展标记语言,是一种简单的数据存储语言,XML被设计用来传输和存储数据

  • 存储:可用来存放配置文件,例如java的配置文件
  • 传输:网络传输时以这种格式存在,例如早期ajax传输的数据、soap协议等

XML格式说明:

Tag:标签,如country标签

Element:被Tag包围的部分,值,如2,2023等

Attribute:标签的属性,如county标签的name

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

注意:在Python开发中用的相对来比较少,作为了解即可
(微信支付、微信公众号消息处理时会用到基于xml传输数据)
例如:https://developers.weixin.qq.com/doc/offiaccount/Message_Management/Receiving_standard_messages.html

  • 取xml文件和内容
# 读取XML文件

from xml.etree import ElementTree as ET

# ET去打开xml文件
tree = ET.parse("files/test.xml")

# 获取根标签
root = tree.getroot()
print(root)            # <Element 'data' at 0x7f94e02763b0>
  • 读取节点数据
from xml.etree import ElementTree as ET

content = """
<data>
    <country name="Liechtenstein" id="999" >
        <rank>2</rank>
        <year>2023</year>
        <gdppc>141100</gdppc>
        <neighbor direction="E" name="Austria" />
        <neighbor direction="W" name="Switzerland" />
    </country>
     <country name="Panama">
        <rank>69</rank>
        <year>2026</year>
        <gdppc>13600</gdppc>
        <neighbor direction="W" name="Costa Rica" />
        <neighbor direction="E" name="Colombia" />
    </country>
</data>
"""

# 获取根标签 data
root = ET.XML(content)

country_object = root.find("country")
print(country_object.tag, country_object.attrib)
gdppc_object = country_object.find("gdppc")
print(gdppc_object.tag,gdppc_object.attrib,gdppc_object.text)
  • 修改和删除节点
from xml.etree import ElementTree as ET

content = """
<data>
    <country name="Liechtenstein">
        <rank>2</rank>
        <year>2023</year>
        <gdppc>141100</gdppc>
        <neighbor direction="E" name="Austria" />
        <neighbor direction="W" name="Switzerland" />
    </country>
     <country name="Panama">
        <rank>69</rank>
        <year>2026</year>
        <gdppc>13600</gdppc>
        <neighbor direction="W" name="Costa Rica" />
        <neighbor direction="E" name="Colombia" />
    </country>
</data>
"""

root = ET.XML(content)

# 修改节点内容和属性
rank = root.find('country').find('rank')
print(rank.text)
rank.text = "999"
rank.set('update', '2022-03-14')
print(rank.text, rank.attrib)
# 保存文件
tree = ET.ElementTree(root)
tree.write("files/new.xml", encoding='utf-8')


# 删除节点
root.remove( root.find('country') )
print(root.findall('country'))
# 保存文件
tree = ET.ElementTree(root)
tree.write("files/new.xml", encoding='utf-8')
  • 构建文档(生成xml文件)
# 生成方式1:
"""
<home>
    <son name="儿1">
        <grandson name="儿11"></grandson>
        <grandson name="儿12"></grandson>
    </son>
    <son name="儿2"></son>
</home>
"""
from xml.etree import ElementTree as ET
# 创建根节点
root = ET.Element("home")
# 创建节点大儿子
son1 = ET.Element('son', {'name': '儿1'})
# 创建节点小儿子
son2 = ET.Element('son', {"name": '儿2'})
# 把两个儿子添加到根节点中
root.append(son1)
root.append(son2)
# 创建两个孙子
grandson1 = ET.Element('grandson', {'name': '儿11'})
grandson2 = ET.Element('grandson', {'name': '儿12'})
# 将两个孙子加入大儿子节点
son1.append(grandson1)
son1.append(grandson2)

 # 生成文档对象
tree = ET.ElementTree(root)
tree.write('files/new.xml', encoding='utf-8', short_empty_elements=False)  # short_empty_elements=False 生成xml短标签

案例:

# 将content构建成字典 (tag:text)

content = """<xml>
    <ToUserName><![CDATA[gh_7f083739789a]]></ToUserName>
    <FromUserName><![CDATA[oia2TjuEGTNoeX76QEjQNrcURxG8]]></FromUserName>
    <CreateTime>1395658920</CreateTime>
    <MsgType><![CDATA[event]]></MsgType>
    <Event><![CDATA[TEMPLATESENDJOBFINISH]]></Event>
    <MsgID>200163836</MsgID>
    <Status><![CDATA[success]]></Status>
</xml>"""

from xml.etree import ElementTree as ET

info = {}
root = ET.XML(content)
for node in root:
    # print(node.tag,node.text)
    info[node.tag] = node.text
print(info)

5. Excel文件

Python中操作Excel需要安装第三方模块 pip install


5.1 读Excel

from openpyxl import load_workbook
wb = load_workbook("files/test.xlsx")

# 1. 获取excel文件中的所有sheet名称
"""
print(wb.sheetnames) # ['Sheet1', 'Sheet2', 'Sheet3', 'Sheet4']
"""

# 2. 选择sheet,基于sheet名称
"""
sheet = wb["Sheet1"]
cell = sheet.cell(1, 2)  # 读取第一行,第二列
print(cell.value)
"""

# 3. 选择sheet,基于索引位置
"""
sheet = wb.worksheets[0]
cell = sheet.cell(1,2)
print(cell.value)
"""

# 4. 取所有Sheet的第一行第一列
"""
for name in wb.sheetnames:
    sheet = wb[name]
    cell = sheet.cell(1, 1)
    print(cell.value)
for sheet in wb.worksheets:
    cell = sheet.cell(1, 1)
    print(cell.value)
for sheet in wb:
    cell = sheet.cell(1, 1)
    print(cell.value)
"""

# 5. 获取某个单元格
"""
v1 = sheet["A2"].value
v2 = sheet["D4"].value
print(v1)
print(v2)
"""

# 6. 获取第N行所有的单元格
"""
for cell in (sheet[1]):      # 第一行
    print(cell.value)
"""  

# 7. 获取所有行的数据 (获取某一列数据)
"""
for row in sheet.rows:
# for row in sheet.item_rows(2): # 从第几行开始读
    print(row,row[0].value,row[1].value)  # 所有行,所有行的第一列,所有行的第二列
"""

# 8. 获取所有列的数据
"""
for col in sheet.columns:
    print(row,col[0].value,col[1].value)   # 所有列,所有列的第一行,所有列的第二行
"""
  • 读合并的excel
    • 读合并的excel的value值为None
from openpyxl import load_workbook
wb = load_workbook("files/test.xlsx")
sheet = wb.worksheets[1]

c1 = sheet.cell(1,1)  # 正常单元格
print(c1)       # <Cell 'Sheet2'.A1>
print(c1.value) # 用户信息

c2 = sheet.cell(1,2)  # 合并的单元格
print(c2)       # <MergedCell 'Sheet2'.B1>
print(c2.value) # None

for row in sheet.rows:
    print(row)
>>> 输出结果
(<Cell 'Sheet2'.A1>, <MergedCell 'Sheet2'.B1>, <Cell 'Sheet2'.C1>)
(<Cell 'Sheet2'.A2>, <Cell 'Sheet2'.B2>, <Cell 'Sheet2'.C2>)
(<Cell 'Sheet2'.A3>, <Cell 'Sheet2'.B3>, <Cell 'Sheet2'.C3>)
(<MergedCell 'Sheet2'.A4>, <Cell 'Sheet2'.B4>, <Cell 'Sheet2'.C4>)
(<Cell 'Sheet2'.A5>, <Cell 'Sheet2'.B5>, <Cell 'Sheet2'.C5>)

5.2 写Excel

  • 原Excel文件基础上写内容
from openpyxl import load_workbook
wb = load_workbook("files/test.xlsx")
sheet = wb.worksheets[0]

# 找到单元格并修改单元格内容
cell = sheet.cell(1,1)
cell.value = "new_value"

# 将excel文件保存到files/test2.xlsx 中
wb.save("files/test2.xlsx")
  • 新创建Excel文件写内容
from openpyxl import workbook
# 创建execl - 放到内存中,且默认会创建一个sheet (名称为sheet) 
wb = workbook.Workbook()
sheet = wb.worksheets[0] # 或 sheet = wb["Sheet"]

# 找到单元格并修改单元格内容
cell = sheet.cell(1,1)
cell.value = "A1,1"

# 将excel保存为文件 files/test3.xlsx
wb.save("files/test3.xlsx")
  • 其他操作
from openpyxl import workbook
# 创建execl - 放到内存中,且默认会创建一个sheet (名称为sheet)
wb = workbook.Workbook()

# 1. 修改sheet名称
"""
sheet = wb.worksheets[0]
sheet.title = "数据集"
wb.save("files/test4.xlsx")
"""

# 2. 创建sheet并设置sheet颜色
"""
sheet = wb.create_sheet("工作内容",1)  # 放在索引1的位置,前面会自动创建索引0的sheet(sheet)
sheet.sheet_properties.tabColor = "1072BA"
wb.save("files/test5.xlsx")
"""

# 3. 默认打开的sheet
"""
wb.active = 0 
"""

# 4. 拷贝sheet
"""
# sheet = wb['数据集']
sheet = wb.create_sheet("数据集")
sheet.sheet_properties.tabColor = "1072BA"
new_sheet = wb.copy_worksheet(wb["Sheet"])
new_sheet.title = "新数据集"
wb.save("files/test6.xlsx")
"""

# 5. 删除sheet
del wb["数据集"]
wb.save("files/test7.xlsx")

6. 压缩文件

  • python内置的shutil模块可以实现对压缩文件的操作
  • 路径:windows路径使用的是 \  ,linux路径使用的是/
    在windows中这种路径 "D:\nxxx\txxx\xx" 程序会报错,因为在路径中存在特殊符 \n换行符\t制表符,python解释器无法自动区分,可以采用两种方式:
    • 加转义符: "D:\\nxxx\\txxx\\xx"
    • 路径前加r:r"D:\nxxx\txxx\xx"
import shutil
import os

src_dir = r'C:\Users\chong\Desktop\学习笔记\Kubernetes'
back_dir = r'C:\Users\chong\Desktop\backup'
back_file = os.path.join(back_dir,'k8s')
unpack_file = os.path.join(back_dir,'k8s.zip')

# 1. 压缩文件
# base_name,压缩后的压缩包文件
# format,压缩的格式,例如:"zip", "tar", "gztar", "bztar", or "xztar".
# root_dir,要压缩的文件夹路径
if not os.path.exists(back_dir):
    os.mkdir(back_dir)
shutil.make_archive(base_name=back_file,format='zip',root_dir=src_dir)

# 2. 解压文件
# filename,要解压的压缩包文件
# extract_dir,解压的路径
# format,压缩文件格式
shutil.unpack_archive(filename=unpack_file,format='zip',extract_dir=back_dir)
print(unpachk_file)

7. 练习题

# 补充一个python内置功能 enumerate
data_list = ['a', 'b', 'c', 'd', 'e']

for index, item in enumerate(data_list, 1):  # enumerate每次会将(data_list,1)中的数字自加1
    print(index, item)
  1. 基于csv格式实现 用户注册 & 登录认证
  • 用户注册时,新注册用户要写入文件csv文件中,输入q退出
  • 用户登录时,逐行读取csv文件中的用户信息并进行校验
  • 文件路径使用os模块构造的绝对路径的方式
import os

# 文件路径处理
base_path = os.path.dirname(os.path.abspath(__file__))
db_file_path = os.path.join(base_path, 'files', 'db.csv')

# 用户注册
while True:
    choice = input("是否进行用户注册(Y/N)?")
    if choice.upper() not in {"Y", "N"}:
        print("输入格式错误")
        continue
    if choice.upper() == "N":
        break
    with open(db_file_path, mode='a', encoding='utf-8') as file_object:
        while True:
            username = input("请输入用户名: ")
            if username.upper() == "Q":
                break
            pwd = input("请输入密码:")
            file_object.write(f'{username},{pwd}\n')
            file_object.flush()
    break

# 用户登陆
username = input("请输入用户名:")
passwd = input("请输入密码:")
if not os.path.exists(db_file_path):
    print("用户文件不存在")
else:
    with open(db_file_path, mode="rt", encoding='utf-8') as file_object:
        for line in file_object:
            line_list = line.strip().split(",")
            if line_list[0] == username and line_list[1] == passwd:
                print("登陆成功")
                break
        else:
            print("用户名或密码错误")
  1. 补充代码,实现取网上获取指定地区的天气信息,并写入到Excel中
import os
import requests
from openpyxl import workbook
from xml.etree import ElementTree as ET

# 处理文件路径
base_dir = os.path.dirname(os.path.abspath(__file__))
target_excel_file_path = os.path.join(base_dir,'files', 'weather.xlsx')

# 创建excel且默认会创建一个sheet (默认会创建一个sheet)
wb = workbook.Workbook()
del wb['Sheet']  # 删除默认的sheet

while True:
    city = input("请输入城市(Q/q退出): ")
    if city.upper() == "Q":
        break
    url = "http://ws.webxml.com.cn//WebServices/WeatherWebService.asmx/getWeatherbyCityName?theCityName={}".format(city)
    res = requests.get(url=url)
    # 提取xml格式中的数据
    root = ET.XML(res.text)  # 获取到根标签
    # 为每一个城市创建一个sheet,并且获取xml格式中的数据写入到excel中
    sheet = wb.create_sheet(city)
    for row_index,node in enumerate(root,1):
        cell = sheet.cell(row_index,1)
        cell.value = node.text
wb.save(target_excel_file_path)
  1. 读取my.cnf文件内容,并按规则写入Excel中
  • 读取ini格式的文件,并创建一个excel文件,且为每个节点创建一个sheet,然后将节点下的键值写入到excel中,按照如下格式:
    capture_20220316223801961.bmp
  • 首行,字体白色 & 单元格背景色蓝色。
  • 内容均居中。
  • 边框
# my.cnf文件内容
[mysqld]
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
log-bin=py-mysql-bin
character-set-server=utf8
collation-server=utf8_general_ci
log-error=/var/log/mysqld.log
# Disabling symbolic-links is recommended to prevent assorted security risks
symbolic-links=0
 
[mysqld_safe]
log-error=/var/log/mariadb/mariadb.log
pid-file=/var/run/mariadb/mariadb.pid
 
[client]
default-character-set=utf8
import os
import configparser
from openpyxl import workbook
from openpyxl.styles import Alignment, Border, Side, Font, PatternFill

# 文件路径的处理
base_path = os.path.dirname(os.path.abspath(__file__))
file_path = os.path.join(base_path, 'files', 'my.cnf')
target_excel_file_path = os.path.join(base_path,'files','my.xlsx')

# 创建excel且默认会创建一个sheet
wb = workbook.Workbook()
del wb['Sheet']

# 解析文件
config = configparser.ConfigParser()
config.read(file_path, encoding='utf-8')

# 循环获取每个节点,并为每个节点创建一个sheet
for section in config.sections():
    sheet = wb.create_sheet(section)

    # 边框和居中(表头和内容都需要)
    side = Side(style="thin", color="000000")
    border = Border(top=side, bottom=side, left=side, right=side)
    align = Alignment(horizontal="center", vertical='center')

    # 为此在sheet设置表头
    title_dict = {"A1": "键", "B1": "值"}
    for postion, text in title_dict.items():
        cell = sheet[postion]
        # 设置值
        cell.value = text
        # 设置居中
        cell.alignment = align
        # 设置背景色
        cell.fill = PatternFill("solid", fgColor="6495ED")
        # 设置字体颜色
        cell.font = Font(name="微软雅黑", color="FFFFFF")
        # 设置边框
        cell.border = border

    # # 读取次节点下的所有键值,并将键值写入到当前sheet中
    # # (不推荐)
    # row_index = 2  # 内容起始行
    # for key, value in config.items(section):
    #     c1 = sheet.cell(row_index, 1)
    #     c1.value = key
    #     c1.alignment = align
    #     c1.border = border
    #     c2 = sheet.cell(row_index, 2)
    #     c2.value = key
    #     c2.alignment = align
    #     c2.border = border
    #     row_index += 1

    # 推荐此方法
    row_index = 2  # 内容起始行
    for group in config.items(section):      # group是一个元组 ('datadir','/var/lib/mysqld')
        for col, text in enumerate(group, 1):
            cell = sheet.cell(row_index, col)
            cell.alignment = align
            cell.border = border
            cell.value = text
        row_index += 1
wb.save(target_excel_file_path)
  1. 完成压缩包操作
  • 下载压缩包
  • 将下载的文件保存到当前执行脚本同级目录下
  • 将下载下来的文件解压到 /files/html/ 目录下
import requests
import os
import shutil

base_dir = os.path.dirname(os.path.abspath(__file__))
download_folder = os.path.join(base_dir, 'files', 'package')
if not os.path.exists(download_folder):
    os.mkdir(download_folder)
# 1.下载文件
file_url = 'https://files.cnblogs.com/files/wupeiqi/HtmlStore.zip'
res = requests.get(url=file_url)

# 2.将下载的文件保存到当前执行脚本同级目录下 /files/package/ 目录下(且文件名为HtmlStore.zip)
file_name = file_url.split('/')[-1]   # HtmlStore.zip
zip_file_path = os.path.join(download_folder, file_name)
with open(zip_file_path, mode='wb') as file_object:
    file_object.write(res.content)
# 3.在将下载下来的文件解压到 /files/html/ 目录下
unpack_floder = os.path.join(base_dir, 'files', 'html')   # 路径如果不存在会自动创建
shutil.unpack_archive(filename=zip_file_path, extract_dir=unpack_floder, format='zip')

标签:files,f1,sheet,函数,文件,python,模块,print,wb
From: https://www.cnblogs.com/ican97/p/17777475.html

相关文章

  • python基础-函数与模块2
    目录1.初识函数2.函数的参数2.1参数2.2默认参数2.3动态参数3.函数的返回值4.练习题1.初识函数面向过程编程:按照业务逻辑从上到下逐步完成函数式编程:利用函数编程函数,是一堆功能代码的集合def函数名():函数内编写代码......函数名()definfo(......
  • python基础-面向对象3
    目录1.继承补充1.1mro和c3算法1.2py2和py3继承区别2.内置函数补充3.异常处理3.1异常细分3.2自定义异常和抛出异常3.3finally和else3.3.1特殊的finally3.3.2else3.3.3traceback3.4异常练习题4.反射4.1一切皆对象4.2import_module+反射5.练习题1.继承补充......
  • python基础-面向对象2
    目录1.成员1.1变量1.2方法1.3属性2.成员修饰符3.对象嵌套4.特殊方法5.练习题1.成员面向对象中的所有成员如下:变量实例变量类变量方法绑定方法类方法静态方法属性1.1变量实例变量,属于对象,每个对象中各自维护自己的数据类变量,属于类,可以被所有对象......
  • python基础-数据类型(字符串-布尔-整数)
    目录1.整数(int)1.1定义1.2独有功能1.3公共功能1.4转换1.5其他1.5.1长整型1.5.2地板除1.5.3其它2.布尔(bool)2.1定义2.2独有功能2.3公共功能2.4转换2.5其他做条件自动转换3.字符串(str)3.1定义3.2独有功能3.2.1练习题3.3公共功能3.4转换3.5其他4.练习题......
  • python异常处理else和finally的区别
    Python3错误和异常|菜鸟教程(runoob.com)try/except...elsetry/except 语句还有一个可选的 else 子句,如果使用这个子句,那么必须放在所有的except子句之后。else子句将在try子句没有发生任何异常的时候执行。以下实例在try语句中判断文件是否可以打开,如果打开文......
  • 函数的定义
    函数的定义函数更多的是一种思想,他不是一种技术定义函数的方式'''def函数名():#定义阶段(造车轮阶段) """函数注释写在这里"""#函数相当于工具,注释相当于工具的说明书 <代码块>#使用函数名()#调用阶段(开车阶段)'''定义阶段不执行函数体代码,只检测语法deffun......
  • 函数基础小结
    函数基础小结计算机的组成之编程什么是编程语言什么是编程为什么要编程计算机的五大组成部分CPU内存外存输入设备输出设备32位和64位多核CPU应用程序的启动机械硬盘的工作原理计算机操作系统什么是文件什么是应用程序操作系统有什么用计算机的三大组成硬件操......
  • Mac OS安装Python的pip
    最近牛牛的同学在学习python,但当他使用numpy时出现了报错(。•́︿•̀。)原因为他的python没有numpy这个库(这个故事很典)。然鹅雪上加霜的是,他的电脑是Mac,没有Windows的cmd...牛牛还没碰过苹果电脑,后面通过查找百度发现在苹果里这玩意儿叫Terminal,经历千辛万苦打开Terminal并开始pip后,......
  • 【Python&GIS】基于Python批量合并矢量数据
    ​老样子最近有项目需要将N个矢量文件合并成一个,总不能用ArcGIS一个个导入吧。所以我就想着用Python编个程序实现批量合并矢量。我之前也发了一些关于Python操作矢量数据的文章:【Python&GIS】Python处理矢量数据的基本操作(查询、修改、删除、新建),如果大家感兴趣可以去我的主......
  • Python深浅拷贝
    Python深浅拷贝拷贝/浅拷贝/深拷贝只针对可变数据类型拷贝(赋值)当lt2为lt的拷贝对象时,lt内的可变类型变化,lt2变化;lt内的不可变类型变化,lt2变化简单的赋值lt=[1,2,3]lt2=ltlt.append(4)print(lt)#因为列表是可变类型,所以lt的值变化,lt2的值也会跟着变化print(l......