第二模块 函数&模块

第一模块主要是学习python基础知识,从第二模块开始就可以通过程序去解决工作中实际的问题。

第二模块的内容主要包含两大部分:

函数

一个用于专门实现某个功能的代码块(可重用)。

  • 内置函数

    len、bin、oct、hex...等
    
  • 自定义函数

    # 定义了一个函数,相当于封装了一个功能代码块
    def send_email():# 写了10行代码,实现了发送邮件。passgoods = [{"name": "电脑", "price": 1999},{"name": "鼠标", "price": 10},{"name": "游艇", "price": 20},{"name": "美女", "price": 998}
    ]
    for index in range(len(goods)):item = goods[index]print(index + 1, item['name'], item['price'])# 调用并执行函数
    send_email()while True:num = input("请输入要选择的商品序号(Q/q):")  # "1"if num.upper() == "Q":breakif not num.isdecimal():print("用输入的格式错误")breaknum = int(num)send_email()if num > 4 or num < 0:print("范围选择错误")breaktarget_index = num - 1choice_item = goods[target_index]print(choice_item["name"], choice_item['price'])send_email()
    

模块

集成了很多功能的函数集合。

  • 内置模块,是Python内部已经定义好的功能集合。

    import random   # 导入内置模块num = random.randint(0,19)
    
    import decimal # 导入内置模块v1 = decimal.Decimal("0.1")
    v2 = decimal.Decimal("0.2")
    v3 = v1 + v2
    print(v3)
    
  • 第三方模块,网上下载别人写好的模块(功能集合)。

  • 自定义模块

day09 文件操作相关


课程目标:掌握基于Python对文件相关操作。

课程概要:

  • 文件操作
  • 文件夹和路径
  • csv格式文件
  • ini格式文件
  • xml格式文件
  • excel文件
  • 压缩文件

注意:每种文件格式包含很多相关操作,大家在学习的过程中只要掌握知识点的用法,参考笔记可以实现相关的练习即可,不必背会(在企业开发过程中也是边搜边实现的)。

1. 文件操作

在学习文件操作之前,先来回顾一下编码的相关以及相关数据类型的知识。

  • 字符串类型(str),在程序中用于表示文字信息,本质上是unicode编码中的二进制。

    name = "轩小陌"
    
  • 字节类型(bytes)

    • 可表示文字信息,本质上是utf-8/gbk等编码的二进制(对unicode进行压缩,方便文件存储和网络传输。)

      name = "轩小陌"
      data = name.encode('utf-8')
      print(data)         # b'\xe6\xad\xa6\xe6\xb2\x9b\xe9\xbd\x90'result = data.decode('utf-8')
      print(result)       # "轩小陌"
      
    • 可表示原始二进制(图片、文件等信息)

1.1 读文件

  • 读文本文件

    # 1.打开文件
    #   - 路径:
    #       相对路径:'info.txt'
    #       绝对路径:'/Users/xuanxiaomo/PycharmProjects/day09/info.txt'
    #   - 模式
    #       rb,表示读取文件原始的二进制      r:读(read)  b:二进制(binary)# 1.打开文件
    file_object = open('info.txt', mode='rb')
    # 2.读取文件内容,并赋值给data
    data = file_object.read()
    # 3.关闭文件
    file_object.close()print(data)      # b'alex-123\n\xe6\xad\xa6\xe6\xb2\x9b\xe9\xbd\x90-123'
    text = data.decode("utf-8")
    print(text)
    
    #  - 模式
    #       rt,表示读取文件的文本数据       r:读(read)  t:文本内容(text)# 1.打开文件
    file_object = open('info.txt', mode='rt', encoding='utf-8')
    # 2.读取文件内容,并赋值给data
    data = file_object.read()
    # 3.关闭文件
    file_object.close()print(data)
    
  • 读图片等非文本内容文件。

    file_object = open('a1.png', mode='rb')
    data = file_object.read()
    file_object.close()print(data) # \x91\xf6\xf2\x83\x8aQFfv\x8b7\xcc\xed\xc3}\x7fT\x9d{.3.\xf1{\xe8\...
    

注意事项:

  • 路径

    • 相对路径:如果在python文件中使用了相对路径,那么在运行python解释器的时候,要确保相对路径的文件放在与解释器同一个路径下,否则解释器将无法找到该文件。

    • 绝对路径

      # 1.打开文件
      file_object = open('/Users/xuanxiaomo/PycharmProjects/day09/info.txt', mode='rt', encoding='utf-8')
      # 2.读取文件内容,并赋值给data
      data = file_object.read()
      # 3.关闭文件
      file_object.close()
      

      windows系统中写绝对路径容易出问题:

      # 单纯输入绝对路径'C:\new\info.txt'会报错,因为系统会将识别\n识别成换行符:
      file_object = open('C:\new\info.txt', mode='rt', encoding='utf-8')# 第一种解决办法:将路径中的'\'全部改成'\\':
      file_object = open('C:\\new\\info.txt', mode='rt', encoding='utf-8')# 第二种解决办法:在路径前面加上字母'r':
      file_object = open(r'C:\new\info.txt', mode='rt', encoding='utf-8')
      
  • 读文件时,如果文件不存在程序会报错,错误信息如下:

    Traceback (most recent call last):File "/Users/xuanxiaomo/PycharmProjects/day09/2.读文件.py", line 2, in <module>file_object = open('infower.txt', mode='rt', encoding='utf-8')
    FileNotFoundError: [Errno 2] No such file or directory: 'info.txt'
    

    因此,我们在打开和读取文件前,可以先判断路径是否存在,如果存在,再进行打开和读取操作:

    import osfile_path = "/Users/xuanxiaomo/PycharmProjects/day09/info.txt"
    exists = os.path.exists(file_path)
    if exists:# 1.打开文件file_object = open('info.txt', mode='rt', encoding='utf-8')# 2.读取文件内容,并赋值给datadata = file_object.read()# 3.关闭文件file_object.close()print(data)
    else:print("文件不存在")
    

1.2 写文件

  • 写文本文件

    # 1.模式:wb(要求写入的内容是字节类型)
    file_object = open("t1.txt", mode='wb')
    # 2.写入内容
    file_object.write("轩小陌".encode("utf-8"))
    # 3.文件关闭
    file_object.close()
    
    # 1.模式:wt(要求写入的内容是文本内容)
    file_object = open("t1.txt", mode='wt', encoding='utf-8')
    # 2.写入内容
    file_object.write("轩小陌")
    # 3.文件关闭
    file_object.close()
    
  • 写图片等文件

    # a1图片文件的内容读取出来:
    f1 = open('a1.png',mode='rb')
    content = f1.read()
    f1.close()
    # 将上面读取到的a1文件的内容写入到a2文件中:
    f2 = open('a2.png',mode='wb')
    f2.write(content)
    f2.close()
    

基础案例:

# 案例1:用户名、密码注册并写入文件中
user = input("请输入用户名:")
pwd = input("请输入密码:")
data = "{}-{}".format(user, pwd)
file_object = open("files/info.txt", mode='wt', encoding='utf-8')
# 用open打开文件时,如果路径下文件不存在,则会创建一个文件
file_object.write(data)
file_object.close()# 案例2:多用户注册
file_object = open("files/info.txt", mode='wt', encoding='utf-8')
while True:user = input("请输入用户名:")if user.upper() == "Q":breakpwd = input("请输入密码:")data = "{}-{}\n".format(user, pwd)file_object.write(data)
file_object.close()

注意:open打开文件时,w写入模式会默认先清空文件内容;再在文件中写入内容。所以为了不要清空文件内容,只在一开始的时候打开文件即可,不要重复打开文件。

进阶案例:(内容超前)

利用Python向某个网址发送请求并获取结果(通过第三方的模块)

  • 下载第三方模块

    pip install requests
    
    # 如果上述方式安装不成功,可以先在python安装路径中找到pip的绝对路径,再进行安装:
    /Library/Frameworks/Python.framework/Versions/3.9/bin/pip3 install requests
    
  • 使用第三方模块

    import requestsres = requests.get(url="网址")
    print(res)
    
# 案例1:去网上下载文本,文本信息写入文件。
import requestsres = 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": "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"}
)# res里面存的是服务器返回的所有信息,包括响应头,响应状态码等
# res.content返回网页的字节码(原始二进制信息bytes)
file_object = open('files/log1.txt', mode='wb')
file_object.write(res.content)
file_object.close()# 案例2:去网上下载一张图片,图片写入本地文件。
import requestsres = requests.get(url="https://hbimg.huabanimg.com/c7e1461e4b15735fbe625c4dc85bd19904d96daf6de9fb-tosv1r_fw1200",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"}
)# res里面存的是服务器返回的所有信息,包括响应头,响应状态码等
# res.content返回网页的字节码(原始二进制信息bytes)
file_object = open('files/picture.png', mode='wb')
file_object.write(res.content)
file_object.close()

1.3 文件打开模式

上文我们基于文件操作基本实现了读、写的功能,其中涉及的文件操作模式:rt、rb、wt、wb,其实在文件操作中还有其他的很多模式。

========= ===============================================================
Character Meaning
--------- ---------------------------------------------------------------
'r'       open for reading (default)
'w'       open for writing, truncating the file first
'x'       create a new file and open it for writing
'a'       open for writing, appending to the end of the file if it exists'b'       binary mode
't'       text mode (default)'+'       open a disk file for updating (reading and writing)The default mode is 'rt' (open for reading text).

关于文件的打开模式常见应用有:

  • 只读:rrtrb (常用)

    • 文件存在,则读
    • 文件不存在,则报错
  • 只写:wwtwb(常用)

    • 文件存在,则清空再写入
    • 文件不存在,则创建后再写入
  • 只写:xxtxb(几乎不用)

    • 文件存在,则报错
    • 文件不存在,则创建后再写入。
  • 只写:aatab【尾部追加】(常用)

    • 文件存在,则在尾部追加。
    • 文件不存在,则创建后再写入。
  • 读写

    • r+、rt+、rb+,注意:读和写的起始位置都要看目前的光标位置

      file_object = open('info.txt', mode='rt+')
      # 读取内容
      data = file_object.read()
      print(data)     # 假设文件中原文本内容为:root-123
      # 写入内容
      file_object.write("alex")
      file_object.close()# 先读后写,写入的位置默认为读取之后的位置
      
      file_object = open('info.txt', mode='rt+')
      # 写入内容
      file_object.write("alex")
      # 读取内容
      data = file_object.read()
      print(data)     # 输出结果:-123
      file_object.close()# 先写后读,写入的位置默认为文件开头,读取的位置为写入文本之后的位置
      
    • w+、wt+、wb+,注意:读的起始位置要看目前光标位置,写的起始位置默认为文件开头(因为w模式每次写入均会先清空文件)

      file_object = open('info.txt', mode='wt+')
      # 读取内容
      data = file_object.read()
      print(data)
      # 写入内容
      file_object.write("你好呀")
      # 将光标位置重置到起始位置
      file_object.seek(0)
      # 读取内容
      data = file_object.read()
      print(data)     # 输出结果:你好呀
      file_object.close()
      
    • x+、xt+、xb+,与w+、wt+、wb+类似,唯一不同是x模式下每次都会创建新文件。

    • a+、at+、ab+,默认光标位置是文件末尾

      file_object = open('info.txt', mode='at+')
      # 写入内容
      file_object.write("轩小陌")
      # 将光标位置重置起始
      file_object.seek(0)
      # 读取内容
      data = file_object.read()
      print(data)     # 输出结果:原文本内容+轩小陌
      file_object.close()
      

案例:多用户注册

file_object = open('files/account.txt', mode='a')
# 相比上面用w模式打开文件,用a模式打开文件可以保证文件内原数据不会被清空
while True:user = input("用户名:")if user.upper() == "Q":breakpwd = input("密码:")data = "{}-{}\n".format(user, pwd)file_object.write(data)file_object.close()

1.4 常见功能

在上述对文件的操作中,我们只使用了write和read来对文件进行读写,其实在文件操作中还有很多其他的功能来辅助实现更好的读写文件的内容。

1.4.1 read:读

  • 读所有【常用】

    f = open('info.txt', mode='r',encoding='utf-8')
    data = f.read()
    f.close()
    
    f = open('info.txt', mode='rb')
    data = f.read()
    f.close()
    
  • 读n个字符(字节)【有时会用】

    f = open('info.txt', mode='r', encoding='utf-8')
    data = f.read(1)   # 读1个字符
    f.close()
    print(data)
    
    f = open('info.txt', mode='rb')
    data = f.read(3)   # 读3个字节
    f.close()
    print(data, type(data))  # 输出结果:b'\xe6\xad\xa6' <class 'bytes'>
    

1.4.2 readline:读一行内容

f = open('info.txt', mode='r', encoding='utf-8')
v1 = f.readline()      # 读第一行内容
v2 = f.readline()      # 读第二行内容
...
f.close()

1.4.3 readline加强版:for循环读取文件每行内容

f = open('info.txt', mode='r', encoding='utf-8')
for line in f:print(line.strip())
f.close()

1.4.4 readlines:读所有行内容,并将每行内容作为列表的一个元素

f = open('info.txt', mode='rb')
data_list = f.readlines()
print(data_list)
f.close()

1.4.5 write:写

f = open('info.txt', mode='a',encoding='utf-8')
f.write("轩小陌")
f.close()
f = open('info.txt', mode='ab')
f.write( "轩小陌".encode("utf-8") )
f.close()

1.4.6 flush:将缓冲区的内容刷到硬盘

f = open('info.txt', mode='a',encoding='utf-8')while True:f.write("轩小陌")  # write不是直接写到硬盘上,而是先写在缓冲区,系统会不定时将缓冲区的内容刷到硬盘。f.flush() # 使用flush()可以保证写入的内容立即刷到硬盘上f.close()

1.4.7 seek:将光标移动到指定字节的位置

f = open('info.txt', mode='r+', encoding='utf-8')f.seek(3)
f.write("轩小陌")f.close()

注意:在a模式下,调用write在文件中写入内容时,永远只能将内容写入到尾部,不会写到光标的位置。

1.4.8 tell:获取当前光标位置

f = open('info.txt', mode='r', encoding='utf-8')p1 = f.tell()
print(p1)       # 初始位置:0
f.read(3)       # 读3个字符,3*3=9个字节
p2 = f.tell()
print(p2)       # 当前位置:9f.close()
f = open('info.txt', mode='rb')p1 = f.tell()
print(p1)       # 初始位置:0
f.read(3)       # 读3个字节
p2 = f.tell()
print(p2)       # 当前位置:3f.close()

1.5 上下文管理

上面对文件进行操作时,每次都要打开和关闭文件,比较繁琐且容易忘记关闭文件。因此在以后进行文件操作时,推荐使用with上下文管理,它可以实现自动关闭文件。

with open("xxxx.txt", mode='rb') as file_object:data = file_object.read()print(data)

在Python 2.7 后,with还支持同时对多个文件的上下文进行管理:

with open("xxxx.txt", mode='rb') as f1, open("xxxx.txt", mode='rb') as f2:pass

练习题

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

    import requestsres = requests.get(url="https://f.video.weibocdn.com/000pTZJLgx07IQgaH7HW010412066BJV0E030.mp4?label=mp4_720p&template=1280x720.25.0&trans_finger=1f0da16358befad33323e3a1b7f95fc9&media_id=4583105541898354&tp=8x8A3El:YTkl0eM8&us=0&ori=1&bf=2&ot=h&ps=3lckmu&uid=3ZoTIp&ab=3915-g1,966-g1,3370-g1,3601-g0,3601-g0,3601-g0,1493-g0,1192-g0,1191-g0,1258-g0&Expires=1608204895&ssig=NdYpDIEXSS&KID=unistore,video",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"}
    )# 视频的文件内容
    res.content# 请补充代码:
    with open(r'file/nba.mp4',mode='wb') as f:f.write(res.content)
    
  2. 日志分析,计算某用户223.73.89.192访问次数。日志文件如下:access.log

    49.89.167.91 - - [17/Dec/2020:03:43:50 +0800] "GET /wiki/detail/3/40 HTTP/1.1" 301 0 "-" "Mozilla/5.0(Linux;Android 5.1.1;OPPO A33 Build/LMY47V;wv) AppleWebKit/537.36(KHTML,link Gecko) Version/4.0 Chrome/43.0.2357.121 Mobile Safari/537.36 LieBaoFast/4.51.3" "-"
    49.89.167.91 - - [17/Dec/2020:03:44:11 +0800] "GET /wiki/detail/3/40/ HTTP/1.1" 200 8033 "-" "Mozilla/5.0(Linux;Android 5.1.1;OPPO A33 Build/LMY47V;wv) AppleWebKit/537.36(KHTML,link Gecko) Version/4.0 Chrome/43.0.2357.121 Mobile Safari/537.36 LieBaoFast/4.51.3" "-"
    203.208.60.66 - - [17/Dec/2020:03:47:58 +0800] "GET /media/uploads/2019/11/17/pic/s1.png HTTP/1.1" 200 710728 "-" "Googlebot-Image/1.0" "-"
    223.73.89.192 - - [17/Dec/2020:03:48:26 +0800] "GET /wiki/detail/3/40/ HTTP/1.1" 200 8033 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36 Edg/87.0.664.60" "-"
    223.73.89.192 - - [17/Dec/2020:03:48:26 +0800] "GET /static/stark/plugins/font-awesome/css/font-awesome.css HTTP/1.1" 200 37414 "https://pythonav.com/wiki/detail/3/40/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36 Edg/87.0.664.60" "-"
    223.73.89.192 - - [17/Dec/2020:03:48:26 +0800] "GET /static/stark/plugins/bootstrap/css/bootstrap.css HTTP/1.1" 200 146010 "https://pythonav.com/wiki/detail/3/40/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36 Edg/87.0.664.60" "-"
    223.73.89.192 - - [17/Dec/2020:03:48:26 +0800] "GET /static/web/css/commons.css HTTP/1.1" 200 3674 "https://pythonav.com/wiki/detail/3/40/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36 Edg/87.0.664.60" "-"
    223.73.89.192 - - [17/Dec/2020:03:48:26 +0800] "GET /static/mdeditor/editormd/css/editormd.preview.css HTTP/1.1" 200 60230 "https://pythonav.com/wiki/detail/3/40/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36 Edg/87.0.664.60" "-"
    223.73.89.192 - - [17/Dec/2020:03:48:26 +0800] "GET /static/stark/js/jquery-3.3.1.min.js HTTP/1.1" 200 86927 "https://pythonav.com/wiki/detail/3/40/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36 Edg/87.0.664.60" "-"
    223.73.89.192 - - [17/Dec/2020:03:48:26 +0800] "GET /static/stark/plugins/bootstrap/js/bootstrap.min.js HTTP/1.1" 200 37045 "https://pythonav.com/wiki/detail/3/40/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36 Edg/87.0.664.60" "-"
    223.73.89.192 - - [17/Dec/2020:03:48:26 +0800] "GET /static/mdeditor/editormd/lib/marked.min.js HTTP/1.1" 200 19608 "https://pythonav.com/wiki/detail/3/40/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36 Edg/87.0.664.60" "-"
    223.73.89.192 - - [17/Dec/2020:03:48:27 +0800] "GET /static/mdeditor/editormd/lib/prettify.min.js HTTP/1.1" 200 17973 "https://pythonav.com/wiki/detail/3/40/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36 Edg/87.0.664.60" "-"
    223.73.89.192 - - [17/Dec/2020:03:48:27 +0800] "GET /static/mdeditor/editormd/fonts/fontawesome-webfont.woff2?v=4.3.0 HTTP/1.1" 200 56780 "https://pythonav.com/static/mdeditor/editormd/css/editormd.preview.css" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36 Edg/87.0.664.60" "-"
    223.73.89.192 - - [17/Dec/2020:03:48:27 +0800] "GET /static/mdeditor/editormd/editormd.js HTTP/1.1" 200 163262 "https://pythonav.com/wiki/detail/3/40/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36 Edg/87.0.664.60" "-"
    223.73.89.192 - - [17/Dec/2020:03:48:28 +0800] "GET /static/mdeditor/mdeditor-preview-init.js HTTP/1.1" 200 261 "https://pythonav.com/wiki/detail/3/40/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36 Edg/87.0.664.60" "-"
    223.73.89.192 - - [17/Dec/2020:03:48:29 +0800] "GET /static/stark/plugins/font-awesome/fonts/fontawesome-webfont.woff2?v=4.7.0 HTTP/1.1" 200 77160 "https://pythonav.com/static/stark/plugins/font-awesome/css/font-awesome.css" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36 Edg/87.0.664.60" "-"
    223.73.89.192 - - [17/Dec/2020:03:48:29 +0800] "GET /media/uploads/2019/02/22/Gobook/_book/ssl2.png HTTP/1.1" 200 203535 "https://pythonav.com/wiki/detail/3/40/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36 Edg/87.0.664.60" "-"# 请补充代码:
    with open('file/access.log',mode='rt',encoding='utf-8') as f:count = 0for line in f:if line.startswith('223.73.89.192'):count += 1
    print(count)
    
  3. 日志分析升级,计算所有用户的访问次数。

    dic = {}
    with open('file/access.log', mode='r', encoding='utf-8') as f:for line in f:key = line.split(' ')[0]if key not in dic.keys():dic[key] = 0dic[key] += 1
    print(dic)
    
  4. 筛选出股票 当前价大于 20 的所有股票数据。

    股票代码,股票名称,当前价,涨跌额,涨跌幅,年初至今,成交量,成交额,换手率,市盈率(TTM),股息率,市值
    SH601778,N晶科,6.29,+1.92,+43.94%,+43.94%,259.66万,1625.52万,0.44%,22.32,-,173.95亿
    SH688566,吉贝尔,52.66,+6.96,+15.23%,+122.29%,1626.58万,8.09亿,42.29%,89.34,-,98.44亿
    SH688268,华特气体,88.80,+11.72,+15.20%,+102.51%,622.60万,5.13亿,22.87%,150.47,-,106.56亿
    SH600734,实达集团,2.60,+0.24,+10.17%,-61.71%,1340.27万,3391.14万,2.58%,亏损,0.00%,16.18亿
    SH900957,凌云B股,0.36,+0.033,+10.09%,-35.25%,119.15万,42.10万,0.65%,44.65,0.00%,1.26亿
    SZ000584,哈工智能,6.01,+0.55,+10.07%,-4.15%,2610.86万,1.53亿,4.36%,199.33,0.26%,36.86亿
    SH600599,熊猫金控,6.78,+0.62,+10.06%,-35.55%,599.64万,3900.23万,3.61%,亏损,0.00%,11.25亿
    SH600520,文一科技,8.21,+0.75,+10.05%,-24.05%,552.34万,4464.69万,3.49%,亏损,0.00%,13.01亿
    SH603682,锦和商业,11.73,+1.07,+10.04%,+48.29%,2746.63万,3.15亿,29.06%,29.62,-,55.42亿
    SZ300831,派瑞股份,12.27,+1.12,+10.04%,+208.29%,25.38万,311.41万,0.32%,60.59,-,39.26亿# 请补充代码:
    with open('file/stock.txt',mode='rt',encoding='utf-8') as f:f.readline()for line in f:if float(line.split(',')[2]) > 20:print(line.strip())
    
  5. 根据要求修改文件的内容,原文件内容如下:ha.conf

    global       log 127.0.0.1 local2daemonmaxconn 256log 127.0.0.1 local2 info
    defaultslog globalmode httptimeout connect 5000mstimeout client 50000mstimeout server 50000msoption  dontlognulllisten stats :8888stats enablestats uri       /adminstats auth      admin:1234frontend oldboy.orgbind 0.0.0.0:80option httplogoption httpcloseoption  forwardforlog globalacl www hdr_reg(host) -i www.luffycity.orguse_backend www.luffycity.com if wwwbackend www.luffycity.comserver 100.1.7.9 100.1.7.9 weight 20 maxconn 3000
    ...
    

    请将文件中的 luffycity修改为 pythonav

    with open('file/ha.conf', mode='r', encoding='utf-8') as f1, open('file/new.conf', mode='w', encoding='utf-8') as f2:for line in f1:new_line = line.replace('luffycity','pythonav')f2.write(new_line)
    # 重命名文件
    import shutil
    shutil.move('file/new.conf','file/ha.conf')
    

2.csv格式文件

逗号分隔值(Comma-Separated Values,CSV,有时也称为字符分隔值,因为分隔字符也可以是其他字符),其文件以纯文本形式存储表格数据(数字和文本)。

对于这种格式的数据,我们需要利用open函数来读取文件并根据逗号分隔的特点来进行处理。

股票代码,股票名称,当前价,涨跌额,涨跌幅,年初至今
SH601778,N晶科,6.29,+1.92,-43.94%,+43.94%
SH688566,吉贝尔,52.66,+6.96,+15.23%,+122.29%
...

练习题案例:下载文档中的所有图片且以用户名为图片名称存储。

ID,用户名,头像
26044585,Hush,https://hbimg.huabanimg.com/51d46dc32abe7ac7f83b94c67bb88cacc46869954f478-aP4Q3V
19318369,柒十一,https://hbimg.huabanimg.com/703fdb063bdc37b11033ef794f9b3a7adfa01fd21a6d1-wTFbnO
15529690,Law344,https://hbimg.huabanimg.com/b438d8c61ed2abf50ca94e00f257ca7a223e3b364b471-xrzoQd
18311394,Jennah·,https://hbimg.huabanimg.com/4edba1ed6a71797f52355aa1de5af961b85bf824cb71-px1nZz
18009711,可洛爱画画,https://hbimg.huabanimg.com/03331ef39b5c7687f5cc47dbcbafd974403c962ae88ce-Co8AUI
30574436,花姑凉~,https://hbimg.huabanimg.com/2f5b657edb9497ff8c41132e18000edb082d158c2404-8rYHbw
17740339,小巫師,https://hbimg.huabanimg.com/dbc6fd49f1915545cc42c1a1492a418dbaebd2c21bb9-9aDqgl
18741964,桐末tonmo,https://hbimg.huabanimg.com/b60cee303f62aaa592292f45a1ed8d5be9873b2ed5c-gAJehO
30535005,TANGZHIQI,https://hbimg.huabanimg.com/bbd08ee168d54665bf9b07899a5c4a4d6bc1eb8af77a4-8Gz3K1
31078743,你的老杨,https://hbimg.huabanimg.com/c46fbc3c9a01db37b8e786cbd7174bbd475e4cda220f4-F1u7MX
25519376,尺尺寸,https://hbimg.huabanimg.com/ee29ee198efb98f970e3dc2b24c40d89bfb6f911126b6-KGvKes
21113978,C-CLong,https://hbimg.huabanimg.com/7fa6b2a0d570e67246b34840a87d57c16a875dba9100-SXsSeY
24674102,szaa,https://hbimg.huabanimg.com/0716687b0df93e8c3a8e0925b6d2e4135449cd27597c4-gWdv24
30508507,爱起床的小灰灰,https://hbimg.huabanimg.com/4eafdbfa21b2f300a7becd8863f948e5e92ef789b5a5-1ozTKq
12593664,yokozen,https://hbimg.huabanimg.com/cd07bbaf052b752ed5c287602404ea719d7dd8161321b-cJtHss
16899164,一阵疯,https://hbimg.huabanimg.com/0940b557b28892658c3bcaf52f5ba8dc8402100e130b2-G966Uz
847937,卩丬My㊊伴er彎,https://hbimg.huabanimg.com/e2d6bb5bc8498c6f607492a8f96164aa2366b104e7a-kWaH68
31010628,慢慢即漫漫,https://hbimg.huabanimg.com/c4fb6718907a22f202e8dd14d52f0c369685e59cfea7-82FdsK
13438168,海贼玩跑跑,https://hbimg.huabanimg.com/1edae3ce6fe0f6e95b67b4f8b57c4cebf19c501b397e-BXwiW6
28593155,源稚生,https://hbimg.huabanimg.com/626cfd89ca4c10e6f875f3dfe1005331e4c0fd7fd429-9SeJeQ
28201821,合伙哼哼,https://hbimg.huabanimg.com/f59d4780531aa1892b80e0ec94d4ec78dcba08ff18c416-769X6a
28255146,漫步AAA,https://hbimg.huabanimg.com/3c034c520594e38353a039d7e7a5fd5e74fb53eb1086-KnpLaL
30537613,配䦹,https://hbimg.huabanimg.com/efd81d22c1b1a2de77a0e0d8e853282b83b6bbc590fd-y3d4GJ
22665880,日后必火,https://hbimg.huabanimg.com/69f0f959979a4fada9e9e55f565989544be88164d2b-INWbaF
16748980,keer521521,https://hbimg.huabanimg.com/654953460733026a7ef6e101404055627ad51784a95c-B6OFs4
30536510,“西辞”,https://hbimg.huabanimg.com/61cfffca6b2507bf51a507e8319d68a8b8c3a96968f-6IvMSk
30986577,艺成背锅王,https://hbimg.huabanimg.com/c381ecc43d6c69758a86a30ebf72976906ae6c53291f9-9zroHF
26409800,CsysADk7,https://hbimg.huabanimg.com/bf1d22092c2070d68ade012c588f2e410caaab1f58051-ahlgLm
30469116,18啊全阿,https://hbimg.huabanimg.com/654953460733026a7ef6e101404055627ad51784a95c-B6OFs4
15514336,W/小哥,https://hbimg.huabanimg.com/a30f5967fc0acf81421dd49650397de63c105b9ead1c-nVRrNl
17473505,椿の花,https://hbimg.huabanimg.com/0e38d810e5a24f91ebb251fd3aaaed8bb37655b14844c-pgNJBP
19165177,っ思忆゜♪,https://hbimg.huabanimg.com/4815ea0e4905d0f3bb82a654b481811dadbfe5ce2673-vMVr0B
16059616,格林熊丶,https://hbimg.huabanimg.com/8760a2b08d87e6ed4b7a9715b1a668176dbf84fec5b-jx14tZ
30734152,sCWVkJDG,https://hbimg.huabanimg.com/f31a5305d1b8717bbfb897723f267d316e58e7b7dc40-GD3e22
24019677,虚无本心,https://hbimg.huabanimg.com/6fdfa9834abe362e978b517275b06e7f0d5926aa650-N1xCXE
16670283,Y-雨后天空,https://hbimg.huabanimg.com/a3bbb0045b536fc27a6d2effa64a0d43f9f5193c177f-I2vHaI
21512483,汤姆2,https://hbimg.huabanimg.com/98cc50a61a7cc9b49a8af754ffb26bd15764a82f1133-AkiU7D
16441049,笑潇啸逍小鱼,https://hbimg.huabanimg.com/ae8a70cd85aff3a8587ff6578d5cf7620f3691df13e46-lmrIi9
24795603,⁢⁢⁢⁢⁢v,https://hbimg.huabanimg.com/a7183cc3a933aa129d7b3230bf1378fd8f5857846cc5-3tDtx3
29819152,妮玛士珍多,https://hbimg.huabanimg.com/ca4ecb573bf1ff0415c7a873d64470dedc465ea1213c6-RAkArS
19101282,陈勇敢❤,https://hbimg.huabanimg.com/ab6d04ebaff3176e3570139a65155856871241b58bc6-Qklj2E
28337572,爱意随风散,https://hbimg.huabanimg.com/117ad8b6eeda57a562ac6ab2861111a793ca3d1d5543-SjWlk2
17342758,幸运instant,https://hbimg.huabanimg.com/72b5f9042ec297ae57b83431123bc1c066cca90fa23-3MoJNj
18483372,Beau染,https://hbimg.huabanimg.com/077115cb622b1ff3907ec6932e1b575393d5aae720487-d1cdT9
22127102,栽花的小蜻蜓,https://hbimg.huabanimg.com/6c3cbf9f27e17898083186fc51985e43269018cc1e1df-QfOIBG
13802024,LoveHsu,https://hbimg.huabanimg.com/f720a15f8b49b86a7c1ee4951263a8dbecfe3e43d2d-GPEauV
22558931,白驹过隙丶梨花泪う,https://hbimg.huabanimg.com/e49e1341dfe5144da5c71bd15f1052ef07ba7a0e1296b-jfyfDJ
11762339,cojoy,https://hbimg.huabanimg.com/5b27f876d5d391e7c4889bc5e8ba214419eb72b56822-83gYmB
30711623,雪碧学长呀,https://hbimg.huabanimg.com/2c288a1535048b05537ba523b3fc9eacc1e81273212d1-nr8M4t
18906718,西霸王,https://hbimg.huabanimg.com/7b02ad5e01bd8c0a29817e362814666a7800831c154a6-AvBDaG
31037856,邵阳的小哥哥,https://hbimg.huabanimg.com/654953460733026a7ef6e101404055627ad51784a95c-B6OFs4
26830711,稳健谭,https://hbimg.huabanimg.com/51547ade3f0aef134e8d268cfd4ad61110925aefec8a-NKPEYX
import os
import requestswith open('file/photo.csv', mode='r', encoding='utf-8') as f:f.readline()for line in f:user_id, user_name, url = line.strip().split(',')# 根据获取到的url通过requests下载到本地res = 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 "})# 通过os模块创建一个文件夹用来储存下载的图片if not os.path.exists('images'):os.makedirs('images')# 将每张图片写入到png文件中,文件名为用户名with open(f'images/{user_name}.png', mode='wb') as f1:f1.write(res.content)

3.ini格式文件

ini文件是Initialization File的缩写,平时用于存储软件的的配置文件。例如:MySQL数据库的配置文件

[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为我们提供了更为方便的方式:configparser

3.1 导入configparser模块并读取文件

# 标准代码写法:
import configparserconfig = configparser.ConfigParser()
config.read('files/my.ini', encoding='utf-8')

3.2 config.sections() 读取所有的节点

ret = config.sections()
print(ret)
>>输出结果:
['mysqld', 'mysqld_safe', 'client']

3.3 config.items() 读取某个节点下所有的键值

item_list = config.items("mysqld_safe")
print(item_list)
>>输出结果:
[('log-error', '/var/log/mariadb/mariadb.log'), ('pid-file', '/var/run/mariadb/mariadb.pid')]

3.4 config.get(节点,键) 读取某个节点下某个键对应的值

value = config.get('mysqld', 'log-bin')
print(value)
>>输出结果:
py-mysql-bin

3.5 config.has_section() 判断节点是否存在

v1 = config.has_section("client")
print(v1)
>>输出结果:
True

3.6 config.add_section() 添加一个新节点

config.add_section("group")
# 注意:添加完新节点后,要执行写入操作
config.write(open('file/my.ini', mode='w', encoding='utf-8'))

3.7 config.set(节点,新键,新值) 在节点下添加的新的键值

config.set('group', 'name', 'xuanxiaomo')
config.set('client', 'name', 'xuanxiaomo')
# 注意:添加完新键值后,要执行写入操作
config.write(open('file/my.ini', mode='w', encoding='utf-8'))

3.8 config.remove_section() 删除指定节点

config.remove_section('client')
# 注意:删除完指定节点后,要执行写入操作
config.write(open('file/my.ini', mode='w', encoding='utf-8'))

3.9 config.remove_option(节点,键) 删除指定节点下的指定个键值

config.remove_option("mysqld", "datadir")
# 注意:删除完指定键值后,要执行写入操作
config.write(open('file/my.ini', mode='w', encoding='utf-8'))

4.XML格式文件

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

  • 存储,可用来存放配置文件,例如:java的配置文件。
  • 传输,网络传输时以这种格式存在,例如:早期ajax传输的数据、soap协议等。
<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开发中用的相对来比较少,作为了解即可。

例如:https://developers.weixin.qq.com/doc/offiaccount/Message_Management/Receiving_standard_messages.html

Python为我们提供了处理xml文件便捷的模块:ElementTree

4.1 读取文件和跟标签

4.1.1 parse() 打开xml文件、getroot() 获取根标签

from lxml import etree as ET# ET去打开xml文件
tree = ET.parse("files/xo.xml")
# 获取根标签
root = tree.getroot()
print(root)
# 输出结果:<Element 'data' at 0x7f94e02763b0>

4.1.2 XML() 获取xml格式文本的根标签

from lxml import etree as ETcontent = """
<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="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>
"""
# 如果已经获取到了xml格式的文本,则可以直接获取到该文本的根标签:
root = ET.XML(content)
print(root)
>>输出结果:<Element 'data' at 0x7fdaa019cea0>

4.2 读取节点数据

4.2.1 find() 找到子标签,tag 获取子标签的名称,attrib 获取子标签的属性(字典),text 获取子标签之间的文本内容

# 找到根标签下的'country'标签:
country_object = root.find("country")
# 获取'country'标签的名称:
print(country_object.tag)
>>输出结果:country# 获取'country'标签的属性:
print(country_object.attrib)
>>输出结果:{'name': 'Liechtenstein'}# 找到'country'标签下的'gdppc'标签:
gdppc_object = country_object.find("gdppc")
或:gdppc_objectroot.find('country').find('rank')
# 获取'gdppc'标签的名称:
print(gdppc_object.tag)
>>输出结果:gdppc# 获取'gdppc'标签的属性:
print(gdppc_object.attrib)
>>输出结果:{}# 获取'gdppc'标签之间的文本内容:
print(gdppc_object.text)
>>输出结果:141100
# 利用循环获取根标签下所有的子标签名称、属性、文本内容
for child in root:print(child.tag, child.attrib)for node in child:print(node.tag, node.attrib, node.text)
>>输出结果:
country {'name': 'Liechtenstein'}
rank {'updated': 'yes'} 2
year {} 2023
gdppc {} 141100
neighbor {'direction': 'E', 'name': 'Austria'} None
neighbor {'direction': 'W', 'name': 'Switzerland'} None
country {'name': 'Panama'}
rank {'updated': 'yes'} 69
year {} 2026
gdppc {} 13600
neighbor {'direction': 'W', 'name': 'Costa Rica'} None
neighbor {'direction': 'E', 'name': 'Colombia'} None

4.2.2 iter() 获取所有的子标签

for child in root.iter('year'):print(child.tag, child.text)
>>输出结果:
year 2023
year 2026

4.2.3 findall() 找到所有的子标签

v1 = root.findall('country')
print(v1)
>>输出结果:
[<Element country at 0x24545be86c0>, <Element country at 0x24545be8640>]

4.3 修改子标签属性和文本内容,删除子标签

rank = root.find('country').find('rank')
# 修改子标签属性
rank.set('update', '2020-11-11')
# 修改子标签的文本内容
rank.text = "999"
print(rank.text, rank.attrib)
>>输出结果:
999 {'updated': 'yes', 'update': '2020-11-11'}
# 注意:修改完之后,还要将其写入到文件中:
tree = ET.ElementTree(root)
tree.write("new.xml", encoding='utf-8')# 删除子标签
root.remove(root.find('country'))
print(root.findall('country'))
>>输出结果:
[<Element country at 0x1aa85038480>]
# 注意:删除完之后,还要将其写入到文件中:
tree = ET.ElementTree(root)
tree.write("new.xml", encoding='utf-8')

4.4 构建xml文档

4.4.1 构建方式一:

from lxml import etree as ET# 创建根标签:
root = ET.Element("home")# 创建2个一级节点标签:
son1 = ET.Element('son', {'name': '儿1'})
son2 = ET.Element('son', {"name": '儿2'})# 在一级节点标签son1中创建2个二级节点标签:
grandson1 = ET.Element('grandson', {'name': '儿11'})
grandson2 = ET.Element('grandson', {'name': '儿12'})
son1.append(grandson1)
son1.append(grandson2)# 将节点标签添加到根标签中:
root.append(son1)
root.append(son2)# 将文档写入文件中:
tree = ET.ElementTree(root)
tree.write('new.xml', encoding='utf-8')>>输出结果:
<home><son name="儿1"><grandson name="儿11"/><grandson name="儿12"/></son><son name="儿2"/>
</home>

4.4.2 构建方式二:

from lxml import etree as ET# 创建根标签:
root = ET.Element("famliy")# 创建2个一级节点标签:
son1 = ET.SubElement(root, "son", attrib={'name': '儿1'})
son2 = ET.SubElement(root, "son", attrib={"name": "儿2"})# 在一级节点标签son1中创建2个二级节点标签:
grandson1 = ET.SubElement(son1, "age", attrib={'name': '儿11'})
grandson1.text = '孙子'# 将文档写入文件中:
et = ET.ElementTree(root)
et.write("test.xml", encoding="utf-8")>>输出结果:
<famliy><son name="儿1"><age name="儿11">孙子</age></son><son name="儿2"/>
</famliy>

案例(解析xml文件中的文本内容):

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 lxml import etree as ETinfo = {}
root = ET.XML(content)
for node in root:info[node.tag] = node.text
print(info)>>输出结果:
{'ToUserName': 'gh_7f083739789a', 'FromUserName': 'oia2TjuEGTNoeX76QEjQNrcURxG8', 'CreateTime': '1395658920', 'MsgType': 'event', 'Event': 'TEMPLATESENDJOBFINISH', 'MsgID': '200163836', 'Status': 'success'}

5.Excel格式文件

Python内部未提供处理Excel文件的功能,想要在Python中操作Excel需要按照第三方的模块。

pip install openpyxl

5.1 读Excel

5.1.1 读取sheet

from openpyxl import load_workbook# 打开Excel文件
wb = load_workbook("files/p1.xlsx")# sheet相关操作
# 1.获取excel文件中的所有sheet名称:
print(wb.sheetnames)
>>输出结果:
['数据导出', '用户列表', 'Sheet1', 'Sheet2']# 2.基于sheet名称选择sheet:
sheet = wb["数据导出"]
# 获取第1行、第2列的单元格:
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.1.2 读取sheet中单元格的数据

from openpyxl import load_workbookwb = load_workbook("file/p1.xlsx")
sheet = wb.worksheets[0]# 1.获取第1行第1列的单元格(注意:单元格位置是从1开始):
cell = sheet.cell(1, 1)
# 1.1 获取单元格的值:
print(cell.value)
>>输出结果:开始# 1.2 获取单元格的样式:
print(cell.style)
>>输出结果:常规# 1.3 获取单元格的字体:
print(cell.font)
>>输出结果:
<openpyxl.styles.fonts.Font object>
Parameters:
name='等线', charset=None, family=2.0, b=False, i=False, strike=None, outline=None, shadow=None, condense=None, color=<openpyxl.styles.colors.Color object>
Parameters:
rgb=None, indexed=8, auto=None, theme=None, tint=0.0, type='indexed', extend=None, sz=11.0, u=None, vertAlign=None, scheme='minor'# 1.4 获取单元格的排列方式:
print(cell.alignment)
>>输出结果:
<openpyxl.styles.alignment.Alignment object>
Parameters:
horizontal=None, vertical='center', textRotation=0, wrapText=None, shrinkToFit=None, indent=0.0, relativeIndent=0.0, justifyLastLine=None, readingOrder=0.0# 2.直接通过Excel表格的索引值获取某个单元格:
c1 = sheet["A2"]
print(c1.value)
c2 = sheet['D4']
print(c2.value)
>>输出结果:287 大白菜# 3.获取第1行所有的单元格:
for cell in sheet[1]:print(cell.value)# 4.获取所有行的数据,从中可以再通过索引获取指定列的数据:
for row in sheet.rows:print(row[0].value)# 5.获取所有列的数据,从中可以通过索引再获取指定行的数据:
for col in sheet.columns:print(col[1].value)

5.1.3 读取sheet中合并单元格的数据

from openpyxl import load_workbookwb = load_workbook("files/p1.xlsx")
sheet = wb.worksheets[2]c1 = sheet.cell(1, 1)
print(c1)
print(c1.value)
>>输出结果:
<Cell 'Sheet1'.A1>
用户信息c2 = sheet.cell(1, 2)
print(c2)
print(c2.value)
>>输出结果:
<MergedCell 'Sheet1'.B1>
None
from openpyxl import load_workbookwb = load_workbook('files/p1.xlsx')
sheet = wb.worksheets[2]
for row in sheet.rows:print(row)>>> 输出结果
(<Cell 'Sheet1'.A1>, <MergedCell 'Sheet1'.B1>, <Cell 'Sheet1'.C1>)
(<Cell 'Sheet1'.A2>, <Cell 'Sheet1'.B2>, <Cell 'Sheet1'.C2>)
(<Cell 'Sheet1'.A3>, <Cell 'Sheet1'.B3>, <Cell 'Sheet1'.C3>)
(<MergedCell 'Sheet1'.A4>, <Cell 'Sheet1'.B4>, <Cell 'Sheet1'.C4>)
(<Cell 'Sheet1'.A5>, <Cell 'Sheet1'.B5>, <Cell 'Sheet1'.C5>)

注意:读取合并单元格时,只有左上角的子单元格为cell,其余子单元格均为MergedCell。读取合并单元格的值时,只有左上角的子单元格才能获取到值,其他子单元格获取的值均为None。

5.2 写Excel

5.2.1 在Excel中写内容的方式可分为两种:

  • 原Excel文件基础上写入内容。
from openpyxl import load_workbookwb = load_workbook('file/p1.xlsx')
sheet = wb.worksheets[0]# 获取单元格,并修改单元格的值
cell = sheet.cell(1, 1)
cell.value = "新的开始"# 将excel文件保存到p1.xlsx文件中
wb.save("files/p1.xlsx")
  • 新创建Excel文件并写入内容。
from openpyxl import workbook# 创建excel且默认会创建一个sheet(名称为Sheet)
wb = workbook.Workbook()sheet = wb.worksheets[0]
或:sheet = wb["Sheet"]# 找到单元格,并修改单元格的内容
cell = sheet.cell(1, 1)
cell.value = "新的开始"# 将excel文件保存到p2.xlsx文件中
wb.save("files/p2.xlsx")

5.2.2 在Excel中写内容的相关操作:

  • 针对sheet进行操作:
from openpyxl import workbookwb = workbook.Workbook() # Sheet# 1.修改sheet名称
sheet = wb.worksheets[0]
sheet.title = "数据集"
wb.save("p2.xlsx")# 2.创建sheet并指定sheet的位置:
sheet = wb.create_sheet("工作计划", 0)
# 2.1 设置sheet的颜色:
sheet.sheet_properties.tabColor = "1072BA"
wb.save("p2.xlsx")# 3.设置默认打开的sheet:
wb.active = 0
wb.save("p2.xlsx")# 4.拷贝sheet:
new_sheet = wb.copy_worksheet(wb["Sheet"])
new_sheet.title = "新的计划"
wb.save("p2.xlsx")# 5.删除sheet:
del wb["用户列表"]
wb.save('p2.xlsx')
  • 针对单元格进行操作:
from openpyxl import load_workbook
# 对单元格的样式进行操作前,需要先导入模块:
from openpyxl.styles import Alignment, Border, Side, Font, PatternFill, GradientFillwb = load_workbook('file/p1.xlsx')
sheet = wb.worksheets[1]# 1.获取某一个单元格,修改值:
# 1.1 方式一:
cell = sheet.cell(1, 1)
cell.value = "开始"
wb.save("p2.xlsx")
# 1.2 方式二:
sheet["B3"] = "Alex"
wb.save("p2.xlsx")# 3.获取若干个单元格,修改值:
cell_list = sheet["B2":"C3"]
for row in cell_list:for cell in row:cell.value = "新的值"
或:
for row in sheet.iter_rows(min_row=5, min_col=1, max_col=7, max_row=10):for cell in row:cell.value = "oo"
wb.save("p2.xlsx")# 4.设置单元格的对齐方式:
cell = sheet.cell(1, 1)
cell.alignment = Alignment(horizontal='center', vertical='distributed', text_rotation=45, wrap_text=True)
# horizontal:水平方向对齐方式("general", "left", "center", "right", "fill", "justify", "centerContinuous", "distributed")
# vertical:垂直方向对齐方式("top", "center", "bottom", "justify", "distributed")
# text_rotation:旋转角度。
# wrap_text:是否自动换行。
wb.save("p2.xlsx")# 5. 设置单元格的边框样式:
cell = sheet.cell(9, 2)
cell.border = Border(top=Side(style="thin", color="FFB6C1"),        # 上边框bottom=Side(style="dashed", color="FFB6C1"),    # 下边框left=Side(style="dashed", color="FFB6C1"),      # 左边框right=Side(style="dashed", color="9932CC"),     # 右边框diagonal=Side(style="thin", color="483D8B"),    # 对角线diagonalUp=True,                                  # 对角线方向:左下~右上diagonalDown=True                                  # 对角线方向:左上~右下
)
# 边框的style有:dashDot','dashDotDot', 'dashed','dotted','double','hair', 'medium', 'mediumDashDot', 'mediumDashDotDot','mediumDashed', 'slantDashDot', 'thick', 'thin'
wb.save("p2.xlsx")# 6.设置单元格的字体样式:
cell = sheet.cell(5, 1)
cell.font = Font(name="微软雅黑", size=45, color="ff0000", underline="single")
wb.save("p2.xlsx")# 7.设置单元格的背景色:
cell = sheet.cell(5, 3)
cell.fill = PatternFill("solid", fgColor="99ccff")
wb.save("p2.xlsx")# 8.设置渐变背景色:
cell = sheet.cell(5, 5)
cell.fill = GradientFill("linear", stop=("FFFFFF", "99ccff", "000000"))
wb.save("p2.xlsx")                # 单元格: 左边颜色   中间颜色  右边颜色# 9.设置宽高(索引值从1开始):
sheet.row_dimensions[1].height = 50
sheet.column_dimensions["E"].width = 100
wb.save("p2.xlsx")# 10.合并单元格:
sheet.merge_cells("B2:D8")
或:sheet.merge_cells(start_row=15, start_column=3, end_row=18, end_column=8)
wb.save("p2.xlsx")
# 10.1 解除合并单元格:
sheet.unmerge_cells("B2:D8")
wb.save("p2.xlsx")# 11.写入公式:
sheet = wb.worksheets[3]
sheet["D2"] = "=B2*C2"
sheet["D3"] = "=SUM(B3,C3)"
wb.save("p2.xlsx")# 12.删除行、列:
sheet.delete_rows(idx=1, amount=20)
sheet.delete_cols(idx=1, amount=3)
# idx:要删除的索引位置   amount:从索引位置开始要删除的行数/列数(默认为1)
wb.save("p2.xlsx")# 13.插入行、列:
sheet.insert_rows(idx=5, amount=10)
sheet.insert_cols(idx=3, amount=2)
# idx:要插入的索引位置   amount:从索引位置开始要插入的行数/列数(默认为1)
wb.save("p2.xlsx")# 14.单元格移动:
sheet.move_range("H2:J10",rows=1, cols=15)
# move_range('H2:J10':需要移动的单元格范围,rows>0:向下移动,cols>0:向右移动)
wb.save("p2.xlsx")
sheet = wb.worksheets[3]
sheet["D1"] = "合计"
sheet["D2"] = "=B2*C2"
sheet["D3"] = "=SUM(B3,C3)"
sheet.move_range("B1:D3",cols=10, translate=True)
# translate=True:单元格中的公式也将随着移动自动更新
wb.save("p2.xlsx")# 16.设置打印区域:
sheet.print_area = "A1:D200"
wb.save("p2.xlsx")# 17.设置每个打印页面的固定表头(顶端标题):
sheet.print_title_cols = "A:D"
sheet.print_title_rows = "1:3"
wb.save("p2.xlsx")

6.压缩文件

基于Python内置的shutil模块可以实现对压缩文件的操作。

import shutil# 1.压缩文件:
shutil.make_archive(base_name=r'datafile',format='zip',root_dir=r'files')
# base_name:压缩后压缩包的放置路径
# format:压缩的格式,例如:"zip", "tar", "gztar", "bztar", or "xztar".
# root_dir:要压缩的文件夹的路径# 2.解压文件:
shutil.unpack_archive(filename=r'datafile.zip', extract_dir=r'xxxxxx\xo', format='zip')
# filename:要解压的压缩包的路径
# extract_dir:解压后文件的放置路径
# format:压缩文件格式

7.路径相关

7.1 转义

windows路径使用的是\,linux路径使用的是/。

特别的,在windows系统中如果有这样的一个路径 D:\nxxx\txxx\x1,程序会报错。因为在路径中存在特殊符 \n(换行符)和\t(制表符),Python解释器无法自动区分。

所以,在windows中编写路径时,一般有两种方式:

  • 加转义符,例如:"D:\\nxxx\\txxx\\x1"
  • 路径前加r,例如:r"D:\\nxxx\\txxx\\x1"

7.2 程序当前路径

项目中如果使用了相对路径,那么一定要注意当前所在的位置。

例如:在/Users/xuanxiaomo/PycharmProjects/CodeRepository/路径下编写 demo.py文件

with open("a1.txt", mode='w', encoding='utf-8') as f:f.write("你好呀")

用以下两种方式去运行:

  • 方式1,文件会创建在 /Users/xuanxiaomo/PycharmProjects/CodeRepository/ 目录下。

    cd /Users/xuanxiaomo/PycharmProjects/CodeRepository/
    python demo.py
    
  • 方式2,文件会创建在 /Users/xuanxiaomo目录下。

    cd /Users/xuanxiaomo
    python /Users/xuanxiaomo/PycharmProjects/CodeRepository/demo.py
    

在不同环境路径中运行文件,为了避免路径不同而报错,可以通过以下方式:

import os# 1.获取当前运行的py脚本所在的绝对路径:
abs = os.path.abspath(__file__)
print(abs)
>>输出结果:/Users/xuanxiaomo/PycharmProjects/luffyCourse/day09/20.路径相关.py
# 获取abs的上一级目录:
path = os.path.dirname(abs)
print(path)
>>输出结果:/Users/xuanxiaomo/PycharmProjects/luffyCourse/day09# 参照上面的方式,设置一个基础路径:
base_dir = os.path.dirname(os.path.abspath(__file__))
# 将基础路径与要运行文件的相对路径拼接起来:
file_path = os.path.join(base_dir, 'files', 'info.txt')
print(file_path)
>>输出结果:/Users/xuanxiaomo/PycharmProjects/luffyCourse/day09/file/info.txt
# 判断路径是否存在,如果存在,再对文件执行相关操作:
if os.path.exists(file_path):file_object = open(file_path, mode='r', encoding='utf-8')data = file_object.read()file_object.close()print(data)
else:print('文件路径不存在')

7.3 文件和路径相关的操作:

import shutil
import os# 1.获取当前脚本绝对路径:
abs_path = os.path.abspath(__file__)
print(abs_path)# 2.获取当前脚本绝对路径的上级目录:
base_path = os.path.dirname( os.path.dirname(路径) )
print(base_path)# 3.路径拼接:
p1 = os.path.join(base_path, 'xx')
p2 = os.path.join(base_path, 'xx', 'oo', 'a1.png')# 4.判断路径是否存在:
exists = os.path.exists(p1)
print(exists)# 5.创建文件夹:
os.makedirs(路径)
# 5.1 判断路径是否存在,如果不存在,则在该路径创建文件夹:
path = os.path.join(base_path, 'xx', 'oo', 'uuuu')
if not os.path.exists(path):os.makedirs(path)# 6.是否路径是否为文件/文件夹:
file_path = os.path.join(base_path, 'xx', 'oo', 'uuuu.png')
is_dir = os.path.isdir(file_path)
print(is_dir)
>>输出结果:Falsefolder_path = os.path.join(base_path, 'xx', 'oo', 'uuuu')
is_dir = os.path.isdir(folder_path)
print(is_dir)
>>输出结果:True# 7.删除指定路径的文件或文件夹:
os.remove("文件路径")path = os.path.join(base_path, 'xx')
shutil.rmtree(path)# 8.拷贝文件夹:
shutil.copytree("/Users/xuanxiaomo/Desktop/图/csdn/","/Users/xuanxiaomo/PycharmProjects/CodeRepository/files")# 9.拷贝文件:
shutil.copy("/Users/xuanxiaomo/Desktop/图/csdn/WX20201123-112406@2x.png","/Users/xuanxiaomo/PycharmProjects/CodeRepository/")
shutil.copy("/Users/xuanxiaomo/Desktop/图/csdn/WX20201123-112406@2x.png","/Users/xuanxiaomo/PycharmProjects/CodeRepository/x.png")# 10.对文件或文件夹进行重命名移动:
shutil.move("/Users/xuanxiaomo/PycharmProjects/CodeRepository/x.png","/Users/xuanxiaomo/PycharmProjects/CodeRepository/xxxx.png")
shutil.move("/Users/xuanxiaomo/PycharmProjects/CodeRepository/files","/Users/xuanxiaomo/PycharmProjects/CodeRepository/images")

今日总结

今天主要围绕着文件 相关的操作来展开进行讲解,让大家能够基于Python处理不同格式的文件。由于涉及的知识点比较多,所以今日的内容学习会比较耗时,但都比较简单,只需要理解后,整理好相关笔记以便后期开发需要时进行查找。

  1. 文件相对路径,在使用相对路径时可能会执行程序的目录不同,导致路径出问题。所以,如若使用相对路径请务必清楚当前运行程序所在目录。

  2. 文件绝对路径(推荐),不要将文件路径写死,而是基于 os 模块中的相关功能自动化获取绝对路径,以方便项目移动到其他文件或电脑上:

    import os
    base_dir = os.path.dirname(os.path.abspath(__file__))
    file_path = os.path.join(base_dir, 'files', 'info.txt')
    
  3. 路径转义

    • 手动写路径,需要自己在路径中添加 r 或 加入 \ 来进行处理。
    • 基于os.path.join拼接的路径,内部会自动处理,不需要手动处理。
  4. 内置函数、内置模块、第三方模块的区别?

  5. 如何去下载安装第三方模块?

    pip install 模块名称
    
    • requests模块,可以用来发送网络请求。
    • openpyxl模块,处理Excel格式的文件。
  6. 基本文件的读写、打开模式、上下文管理。

  7. 其他格式:csv、ini、xml、excel格式的处理。

今日作业

1. 基于csv格式实现 用户的注册 & 登录认证。详细需求如下:

  • 用户注册时,新注册用户要写入文件csv文件中,输入Q或q则退出。
  • 用户登录时,逐行读取csv文件中的用户信息并进行校验。
  • 提示:文件路径须使用os模块构造的绝对路径的方式。
import osbase_dir = os.path.dirname(os.path.abspath(__file__))
file_path = os.path.join(base_dir, 'file', 'load.csv')# 用户注册
while True:choice = input('是否进行用户注册(Y/N):')if choice.upper() not in ('Y','N'):print('输入错误,请重新输入')continueif choice.upper() == 'N':breakwith open(file_path, mode='a', encoding='utf-8') as f:while True:user_name = input('请输入用户名(Q/q退出):')if user_name.upper() == 'Q':breakpassword = input('请输入密码:')f.write(f'{user_name},{password}\n')f.flush()break# 用户登录
print('欢迎登录')
flag = True
while flag:user_name = input('请输入用户名:')password = input('请输入密码:')with open(file_path, mode='r', encoding='utf-8') as f:for line in f:user, pwd = line.strip().split(',')if user_name == user and password == pwd:print('登录成功')flag = Falsebreakelse:print('用户名或密码错误,请重新输入')

2. 补充代码:实现去网上获取指定地区的天气信息,并写入到Excel中。

import os
import requests
from lxml import etree as ET
from openpyxl import workbook# 创建xlsx文件路径:
base_dir = os.path.dirname(os.path.abspath(__file__))
file_path = os.path.join(base_dir, 'weather.xlsx')
# 创建Excel表,删除默认的'Sheet'子表:
wb = workbook.Workbook()
del wb['Sheet']while True:city = input("请输入城市(Q/q退出):")if city.upper() == "Q":breakurl = "http://ws.webxml.com.cn//WebServices/WeatherWebService.asmx/getWeatherbyCityName?theCityName={}".format(city)res = requests.get(url=url)# 1.提取XML格式中的数据:root = ET.XML(res.text.encode('utf-8'))# 2.为每个城市创建一个sheet,并将获取的xml格式中的数据写入到excel中:sheet = wb.create_sheet(city)for index, node in enumerate(root, 1):cell = sheet.cell(index, 1)cell.value = node.text
# 保存Excel到路径:
wb.save(file_path)

3. 读取ini文件内容,按照规则写入到Excel中。

  • 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
    
  • 读取ini格式的文件,并创建一个excel文件,且为每个节点创建一个sheet,然后将节点下的键值写入到excel中,按照如下格式。

    • 首行,字体白色 & 单元格背景色蓝色。
    • 内容均居中。
    • 边框。
import os
import configparser
from openpyxl import workbook
from openpyxl.styles import Alignment, Border, Side, Font, PatternFill, GradientFill# 创建ini文件路径和xlsx文件
base_dir = os.path.dirname(os.path.abspath(__file__))
ini_path = os.path.join(base_dir, 'file', 'work3.ini')
xlsx_path = os.path.join(base_dir, 'file', 'work3.xlsx')# 解析ini文件
config = configparser.ConfigParser()
config.read(ini_path, encoding='utf-8')item_list = config.items()
# 创建Excel表,删除默认的Sheet字表
wb = workbook.Workbook()
del wb['Sheet']# 循环每个节点:
for section in config.sections():# 用节点名称创建sheet: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', wrap_text=True)# 设置每个sheet的表头内容:title_list = {'A1': '键', 'B1': '值'}for position, text in title_list.items():cell = sheet[position]cell.value = textcell.alignment = aligncell.fill = PatternFill('solid', fgColor='6495ED')cell.font = Font(name='微软雅黑', color='FFFFFF')cell.border = border# 循环遍历每个节点下的键值:row_index = 2for item in config.items(section):# 循环每个键值下的键、值,分别写入Excel对应的单元格中:for col_index, text in enumerate(item, 1):cell = sheet.cell(row_index, col_index)cell.value = textcell.alignment = aligncell.border = borderrow_index += 1
wb.save(xlsx_path)

4. 补充代码,实现如下功能。

import requests# 1.下载文件
file_url = 'https://files.cnblogs.com/files/wupeiqi/HtmlStore.zip'
res = requests.get(url=file_url)
print(res.content)# 2.将下载的文件保存到当前执行脚本同级目录下 /files/package/ 目录下(且文件名为HtmlStore.zip)# 设置下载文件夹的路径:
base_dir = os.path.dirname(os.path.abspath(__file__))
file_path = os.path.join(base_dir, 'files', 'package')
if not os.path.exists(file_path):os.makedirs(file_path)
# 设置文件夹下文件的路径
file_name = file_url.split('/')[-1]
zip_path = os.path.join(file_path, file_name)
with open(zip_path, mode='wb') as f:f.write(res.content)# 3.在将下载下来的文件解压到 /files/html/ 目录下
unpack_path = os.path.join(base_dir, 'files', 'html')
shutil.unpack_archive(filename=zip_path, extract_dir=unpack_path, format='zip')

轩小陌的Python笔记-day09 文件操作相关相关推荐

  1. 轩小陌的Python笔记-day06 数据类型

    day06 数据类型(中) 常见的数据类型: int,整数类型(整形) bool,布尔类型 str,字符串类型 list,列表类型 tuple,元组类型 dict,字典类型 set,集合类型 floa ...

  2. 轩小陌的Python笔记-day25 MySQL入门

    第四模块 MySQL数据库 从今天开始将进入第四模块的学习,这个模块就是给大家讲解MySQL数据库. 以前,在开发程序时,我们会把很多的数据和信息存储到某个文件夹中的文件中,例如:user.txt . ...

  3. 轩小陌的Python笔记-day08 模块一总结

    day08 阶段总结和考试题 课程目标:对第一模块 "Python基础" 阶段的知识点进行总结,更好地掌握此模块的相关知识. 课程概要: 代码规范 知识补充 阶段总结(思维导图) ...

  4. 轩小陌的Python笔记-day28 索引、函数及存储过程

    day28 索引和函数及存储过程 课程目标:了解 MySQL 中索引.函数.存储过程.函数.触发器.视图等知识点. 课程概要: 索引 函数 存储过程 视图 触发器 1. 索引 在数据库中索引最核心的作 ...

  5. 轩小陌的Python笔记-day14 自定义模块、第三方模块、内置模块(部分)

    day14 模块 课程目标:掌握Python中常用模块的使用方法. 今日概要: 自定义模块(包) 第三方模块 内置模块[1/2] 1. 自定义模块 1.1 模块和包 import hashlibdef ...

  6. 轩小陌的Python笔记-day05 数据类型

    day05 数据类型(上) 接下来的3篇的内容都是讲解数据类型的知识点,常见的数据类型: int,整数类型(整型) bool,布尔类型 str,字符串类型 list,列表类型 tuple,元组类型 d ...

  7. 轩小陌的Python笔记-day13 匿名函数、生成器、内置函数、推导式

    day13 内置函数和推导式 今日概要: 匿名函数 生成器 内置函数 附加:推导式,属于数据类型的知识,内部的高级的用法会涉及到[生成器]和[函数]的内容. 1. 匿名函数 传统的函数的定义包括了:函 ...

  8. 轩小陌的Python笔记-day11 函数进阶

    day11 函数进阶 目标:掌握函数相关易错点 & 项目开发必备技能. 今日概要: 参数的补充 函数名到底是什么? 返回值和print,傻傻分不清楚. 函数的作用域 1.参数的补充 在函数基础 ...

  9. 轩小陌的Python笔记-day02 快速上手

    day02 快速上手 课程目标:学习Python最基础的语法知识,可以用代码快速实现一些简单的功能. 课程概要: 初识编码(密码本) 编程初体验 输出 初识数据类型 变量 注释 输入 条件语句 1.初 ...

  10. 轩小陌的Python笔记-day15 内置模块(剩余)和开发规范

    day15 内置模块和开发规范 目标:掌握常见的内置模块的使用及了解软件开发的规范. 今日概要: 内置模块 json time datetime re 开发规范 主文件 配置文件 数据 附件 业务代码 ...

最新文章

  1. wxss 点击样式_小程序05-样式WXSS(示例代码)
  2. java的初始化顺序
  3. 院长来信 | 英特尔宋继强:疫情之下对科技创新的再思考,科学为源,技术为器...
  4. IPv6 — IPv4v6 综合组网技术
  5. questasim linux安装包,Ubuntu16.04下Questasim10.7安装(64bit)全攻略
  6. Python之数据重塑——【stack()方法和unstack()方法、pivot()方法】
  7. 启动mq命令 linux,RocketMQ:Linux下启动server和broker的命令
  8. html5折叠卡片,基于HTML5折叠卡片式下拉菜单代码
  9. 奇安信代码安全实验室五人入选“2020微软 MSRC 最具价值安全研究者”榜单
  10. java基础总结05-面向对象
  11. 卡盟主站搭建_搭建卡盟主站下载|搭建卡盟主站教程 (附带源码)百度云_ - 极光下载站...
  12. Hadoop Shell总结
  13. filebeat收集K8S日志,写入自动创建的索引
  14. Android拍照,相册选择图片以及Android6.0权限管理
  15. 塔米狗企业并购与投融资信息服务平台
  16. UGUI源码分析:开关组件Toggle与ToggleGroup
  17. SVPWM空间矢量脉冲宽度调制技术控制电机
  18. 2022年美化UI二开某技术导航天下PHP源码
  19. `spyder总是闪退?spyder打不开?spyder又又又又又出错啦?
  20. BASLER Pylon 抓取策略

热门文章

  1. 死记3dmax快捷键有用么?
  2. 深圳医械帮:一个军团的诞生
  3. Springboot 返回数据提示语 国际化 (AOP实现)
  4. html alpha使用方法,如何使用HTML5画布创建一个带Alpha通道的h264视频?
  5. Android之视频裁剪
  6. 背景图片虚化的效果的css样式的实现
  7. ddwrt(ddwrt和openwrt哪个好)
  8. APKTOOL打包方法
  9. 全国哀悼日 网站变灰代码集锦
  10. RabbitMQ教程(安装与使用详解,Spring集成)