関数&モジュール&ファイル操作関連

1.機能

1. 関数の定義

関数。特定の関数に特化するために使用される (再利用可能な) コードのブロック。

[1] 内蔵関数

len、bin、oct、hex 等

【2】カスタム機能

def send_email():
    # 写了10行代码,实现了发送邮件。
    pass

send_email()
# 定义了一个函数,功能代码块
def send_email():
    # 写了10行代码,实现了发送邮件。
    pass

goods = [
    {
    
    "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":
        break
    if not num.isdecimal():
        print("用输入的格式错误")
        break
    num = int(num)
    send_email()
    if num > 4 or num < 0:
        print("范围选择错误")
        break
    target_index = num - 1
    choice_item = goods[target_index]
    print(choice_item["name"], choice_item['price'])
    send_email()

2、モジュール

1. モジュールの定義

多くの機能を統合した関数のコレクション。

[1] 組み込みモジュールである 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) # 0.3

[2] サードパーティ モジュール、オンラインで他人が作成したダウンロード モジュール (関数コレクション)。

【3】カスタムモジュール

3. ファイル操作関連

各形式には関連する操作が多数含まれており、学習プロセスでは、知識ポイントの使用方法をマスターし、関連する演習を実現するために注釈を参照するだけでよく、暗記する必要はありません。

1. ファイル操作

【1】ファイルの読み込み

  • テキストファイルを読む
# 1.打开文件
#	- 路径:
#		相对路径:'info.txt'
#		绝对路径:'/Users/wupeiqi/PycharmProjects/luffyCourse/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)
# 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\...

== 注意事項 ==

  1. パス
    - 相対パス、現在のプログラムのディレクトリ内のファイルを検索
    - 絶対パス
# 1.打开文件
file_object = open('/Users/wupeiqi/PycharmProjects/luffyCourse/day09/info.txt', mode='rt', encoding='utf-8')
# 2.读取文件内容,并赋值给data
data = file_object.read()
# 3.关闭文件
file_object.close()

Windows システムで絶対パスを記述すると、問題が発生しやすくなります。

# file_object = open('C:\\new\\info.txt', mode='rt', encoding='utf-8')   

file_object = open(r'C:\new\info.txt', mode='rt', encoding='utf-8')    # 直接写win绝对路径会报错,可以在路径前方加上r,或者使用双斜杠 
data = file_object.read()
file_object.close()
print(data)
  1. ファイルを読み取るときに、ファイルが存在しない場合、プログラムはエラーを報告します。
Traceback (most recent call last):
  File "/Users/wupeiqi/PycharmProjects/luffyCourse/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: 'infower.txt'
# 判断路径是否存在:
import os

file_path = "/Users/wupeiqi/PycharmProjects/luffyCourse/day09/info.txt"
exists = os.path.exists(file_path)    #判断路径是否存在,返回一个bool 
if exists:
    # 1.打开文件
    file_object = open('infower.txt', mode='rt', encoding='utf-8')
    # 2.读取文件内容,并赋值给data
    data = file_object.read()
    # 3.关闭文件
    file_object.close()
    print(data)
else:
    print("文件不存在")

【2】ファイルの書き込み

  1. テキストファイルを書き込む
# 1.打开文件
# 路径:t1.txt
# 模式:wb(要求写入的内容需要是字节类型)
file_object = open("t1.txt", mode='wb')

# 2.写入内容
file_object.write(    "张三".encode("utf-8")    )

# 3.文件关闭
file_object.close()
file_object = open("t1.txt", mode='wt', encoding='utf-8')   #通过wt写入内容更方便,不用进行转换

file_object.write("张三")

file_object.close()
  1. 画像やその他のファイルを書き込む
#相当于复制图片
f1 = open('a1.png',mode='rb')
content = f1.read()
f1.close()

f2 = open('a2.png',mode='wb')
f2.write(content)
f2.close()
  1. 規範事例:
# 【1】案例1:用户注册

user = input("请输入用户名:")
pwd = input("请输入密码:")
data = "{}-{}".format(user, pwd)
file_object = open("files/info.txt", mode='wt', encoding='utf-8')   #打开某一文件时,若是文件不存在,则会创建一个
file_object.write(data)
file_object.close()


#【2】 案例2:多用户注册

# 通过w写入文件,先清空文件;再在文件中写入内容。解决方案:不要反复打开文件即可
file_object = open("files/info.txt", mode='wt', encoding='utf-8')  
while True:
    user = input("请输入用户名:")
    if user.upper() == "Q":
        break
    pwd = input("请输入密码:")
    data = "{}-{}\n".format(user, pwd)     #  \n 在程序中是换行的意思,加入后可让输如内容自动换行

    file_object.write(data)
file_object.close()

小規模な先進的なケース: (先)

# 利用Python想某个网址发送请求并获取结果(利用第三方的模块)
# 下载第三方模块requests
pip install requests   # 若使用该方法安装报错,则使用下边的代码进行安装

或者:  /Library/Frameworks/Python.framework/Versions/3.9/bin/pip3 install requests  # 此代码中的路径为py的安装目录
# 使用第三方模块
import requests

res = requests.get(url="网址")
print(res)
# 【1】 案例1:去网上下载一点文本,文本信息写入文件。
import requests

res = 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.content   网络传输的原始二进制信息(bytes)


file_object = open('files/log1.txt', mode='wb')
file_object.write(res.content)
file_object.close()



# 【2】案例2:去网上下载一张图片,图片写入本地文件。
import requests

res = 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"
    }
)

# 网络传输的原始二进制信息(bytes)
# res.content

file_object = open('files/张三.png', mode='wb')
file_object.write(res.content)
file_object.close()

予防

  • パス
    絶対パス
    相対パス
  • ファイルが存在しない場合、w モードは新しいファイルを作成してコンテンツを書き込みます。ファイルが存在する場合、w モードはファイルをクリアしてコンテンツを書き込みます。

【3】ファイルオープンモード

========= ===============================================================
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(理解するだけ)

    存在します。エラーを報告します
    。存在しません。作成して再度書き込みます。

  • a、、、atab末尾に追記】のみを記載(使用)

    存在し、最後に追加されます。
    存在しません。作成して再度書き込みます。

  • 読み書き

    r+、rt+、rb+、デフォルトのカーソル位置: 開始位置

file_object = open('info.txt', mode='rt+')

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

# 写入内容
file_object.write("你好呀")

file_object.close()
file_object = open('info.txt', mode='rt+')

# 写入内容
file_object.write("zhan")

# 读取内容
data = file_object.read()
print(data)  # -123  此处从光标位置开始读取,故没有读取全部内容

file_object.close()

w+、wt+、wb+、デフォルトのカーソル位置:開始位置(クリアファイル)

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+、デフォルトのカーソル位置: 開始位置 (新しいファイル)

a+、at+、ab+、デフォルトのカーソル位置: end

file_object = open('info.txt', mode='at+')

# 写入内容
file_object.write("张三")

# 将光标位置重置起始
file_object.seek(0)

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

file_object.close()

【複数ユーザー登録の場合】

while True:
    user = input("用户名:")
    if user.upper() == "Q":
        break
    pwd = input("密码:")

    data = "{}-{}\n".format(user, pwd)

    file_object = open('files/account.txt', mode='a')
    file_object.write(data)
    file_object.close()
file_object = open('files/account.txt', mode='a')

while True:
    user = input("用户名:")
    if user.upper() == "Q":
        break
    pwd = input("密码:")
    data = "{}-{}\n".format(user, pwd)
    file_object.write(data)

file_object.close()

【4】共通機能

上記のファイル操作では、ファイルの読み取りと書き込みに write と read のみを使用していますが、実際には、ファイル操作には、ファイル コンテンツの読み取りと書き込みを効率的に行うための関数が他にもたくさんあります。

  1. 読んで読んで
  • すべて読む [よく使われる]
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')
# 读1个字符
data = f.read(1)
f.close()

print(data) # 武
f = open('info.txt', mode='r',encoding='utf-8')

# 读1个字符
chunk1 = f.read(1)
chunk2 = f.read(2)
print(chunk1,chunk2)

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

# 读1个字节
data = f.read(3)
f.close()

print(data, type(data))  # b'\xe6\xad\xa6' <class 'bytes'>
f = open('info.txt', mode='rb')

# 读1个字节
chunk1 = f.read(3)
chunk2 = f.read(3)
chunk3 = f.read(1)
print(chunk1,chunk2,chunk3)

f.close()
  1. readline、一行読む
f = open('info.txt', mode='r', encoding='utf-8')

v1 = f.readline()
print(v1)

v2 = f.readline()
print(v2)

f.close()
f = open('info.txt', mode='r', encoding='utf-8')
v1 = f.readline()
print(v1)
f.close()

f = open('info.txt', mode='r', encoding='utf-8')
v2 = f.readline()
print(v2)
f.close()
  1. readlines、すべての行を読み取り、各行をリストの要素として読み取ります。
f = open('info.txt', mode='rb')

data_list = f.readlines()

f.close()

print(data_list)
  1. ループ、大きなファイルの読み取り (readline 拡張版) [共通]
# 大文件读取,且读完后会自动终止,可搭配for循环
f = open('info.txt', mode='r', encoding='utf-8')
for line in f:
    print(line.strip())
f.close()
  1. 書く、書く
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. フラッシュ、ハードディスクへのブラシ
f = open('info.txt', mode='a',encoding='utf-8')

while True:
    # 由于写入不是写到了硬盘,而是写在缓冲区,系统会将缓冲区的内容刷到硬盘,但时间不定,使用flush可将写入缓冲区的内容立即刷到硬盘中。
	f.write("武沛齐")
    f.flush()

f.close()
file_object = open('files/account.txt', mode='a')

while True:
    user = input("用户名:")
    if user.upper() == "Q":
        break
    pwd = input("密码:")
    data = "{}-{}\n".format(user, pwd)
    file_object.write(data)
    file_object.flush()

file_object.close()
  1. カーソル位置を移動 (バイト)
f = open('info.txt', mode='r+', encoding='utf-8')

# 移动到指定字节的位置
f.seek(3)
f.write("武沛齐")

f.close()

注: モードでは、write を呼び出してファイルにコンテンツを書き込む場合、コンテンツは最後まで永久に書き込むことしかできず、カーソル位置には書き込まれません。

  1. 現在のカーソル位置を取得します
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)  # 9

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

p1 = f.tell()
print(p1)  # 0

f.read(3)  # 读3个字节

p2 = f.tell()
print(p2)  # 3

f.close()

[5] コンテキスト管理

これまでファイルを操作する場合、毎回ファイルを開いたり閉じたりする必要があり、面倒でファイルを閉じるのを忘れがちです。

今後ファイル操作を行う場合は、ファイルを自動的に閉じることができるコンテキスト管理と併用することをお勧めします。

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

Python 2.7 以降では、同時に複数のファイルのコンテキスト管理がサポートされています。

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

【6】練習問題

  1. 補足コード: ビデオのダウンロードを実現し、ローカルに保存します。
   import requests
   
   res = 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

完全なコード:

import requests

res = 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"
    }
)

# 视频的文件内容
with open('nba.mp4' ,mode='wb') as file_object:
    file_object.read(res.content)
res.content

  1. 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" "-"

クエリメソッド
分析:

total_count = 0
ip = "223.73.89.192"
with open('files/access.log', mode='r', encoding='utf-8') as file_object:
    for line in file_object:
        if not line.startswith(ip):
            continue
        total_count += 1
print(total_count)
  1. ログ分析がアップグレードされ、すべてのユーザーの訪問数が計算されます。
user_dict = {
    
    }
with open('files/access.log',mode='r',encoding='utf-8') as file_object:
    for line in file_object:
        user_ip = line.split(" ")[0]
        if user_ip in user_dict:
            # user_dict[user_ip] = user_dict[user_ip] + 1
            user_dict[user_ip] += 1
        else:
            user_dict[user_ip] = 1
print(user_dict)
  1. 現在の株価が 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('files/stock.txt', mode='r', encoding='utf-8') as file_object:
    # 1.跳过第一行
    file_object.readline()
    # 2.接着往下读
    for line in file_object:
        text = line.split(',')[2]
        price = float(text)
        if price > 20:
            print(line.strip())
  1. 要件に応じてファイルの内容を変更します。元のファイルの内容は次のとおりです。ha.conf
   global       
           log 127.0.0.1 local2
           daemon
           maxconn 256
           log 127.0.0.1 local2 info
   defaults
           log global
           mode http
           timeout connect 5000ms
           timeout client 50000ms
           timeout server 50000ms
           option  dontlognull
   
   listen stats :8888
           stats enable
           stats uri       /admin
           stats auth      admin:1234
   
   frontend oldboy.org
           bind 0.0.0.0:80
           option httplog
           option httpclose
           option  forwardfor
           log global
           acl www hdr_reg(host) -i www.luffycity.org
           use_backend www.luffycity.com if www
   
   backend www.luffycity.com
           server 100.1.7.9 100.1.7.9 weight 20 maxconn 3000

luffycityファイルを に変更してくださいpythonav

"""
- 文件读到内存,再通过replace(适用于小文件,不适用大文件)
- 挨个位置读文件的内容,遇到luffycity将其替换成pythonav。(不可取)
- 同时打开两个文件,读+写。(适用于小文件,适用大文件)
"""
wit h open('files/ha.conf', mode='r', encoding='utf-8') as read_file_object, open('files/new.conf', mode='w',
                                                                                 encoding='utf-8') as write_file_object:
    for line in read_file_object:
        new_line = line.replace("luffycity", 'pythonav')
        write_file_object.write(new_line)

# 重命名
import shutil

shutil.move("files/new.conf", 'files/ha.conf')

2.csv形式ファイル

カンマ区切り値( 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
```python
import os
import requests

with open('files/mv.csv', mode='r', encoding='utf-8') as file_object:
    file_object.readline()
    for line in file_object:
        user_id, username, url = line.strip().split(',')
        print(username, url)
        # 1.根据URL下载图片
        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"
            }
        )
        # 检查images目录是否存在?不存在,则创建images目录
        if not os.path.exists("images"):
            # 创建images目录
            os.makedirs("images")

        # 2.将图片的内容写入到文件
        with open("images/{}.png".format(username), mode='wb') as img_object:
            img_object.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ではより便利な方法が提供されています。

import configparser

config = configparser.ConfigParser()
config.read('files/my.ini', encoding='utf-8')
# config.read('/Users/wupeiqi/PycharmProjects/luffyCourse/day09/files/my.ini', encoding='utf-8')

# 1.获取所有的节点
"""
result = config.sections()
print(result)  # ['mysqld', 'mysqld_safe', 'client']
"""

# 2.获取节点下的键值
"""
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)
"""

# 3.获取某个节点下的键对应的值
"""
result = config.get("mysqld","collation-server")
print(result)
"""

# 4.其他

# 4.1 是否存在节点
# v1 = config.has_section("client")
# print(v1)

# 4.2 添加一个节点
# config.add_section("group")     #只是添加在内训中,要看到这个节点需要写入
# config.set('group','name','zhangsan')
# config.set('client','name','zhangsan')
# config.write(open('files/new.ini', mode='w', encoding='utf-8'))

# 4.3 删除
# config.remove_section('client')
# config.remove_option("mysqld", "datadir")
# config.write(open('files/new.ini', mode='w', encoding='utf-8'))
  • すべてのノードを読み取ります
import configparser

config = configparser.ConfigParser()
config.read('/Users/wupeiqi/PycharmProjects/luffyCourse/day09/files/my.conf', encoding='utf-8')
# config.read('my.conf', encoding='utf-8')
ret = config.sections()
print(ret) 

>>输出
['mysqld', 'mysqld_safe', 'client']
  • ノードの下のキー値を読み取ります
import configparser

config = configparser.ConfigParser()
config.read('/Users/wupeiqi/PycharmProjects/luffyCourse/day09/files/my.conf', encoding='utf-8')
# config.read('my.conf', encoding='utf-8')
item_list = config.items("mysqld_safe")
print(item_list) 

>>输出
[('log-error', '/var/log/mariadb/mariadb.log'), ('pid-file', '/var/run/mariadb/mariadb.pid')]
  • ノードの下の値を読み取ります(ノード+キーに従って)
import configparser

config = configparser.ConfigParser()
config.read('/Users/wupeiqi/PycharmProjects/luffyCourse/day09/files/my.conf', encoding='utf-8')

value = config.get('mysqld', 'log-bin')
print(value)

>>输出
py-mysql-bin
  • ノードの確認、削除、追加
import configparser

config = configparser.ConfigParser()
config.read('/Users/wupeiqi/PycharmProjects/luffyCourse/day09/files/my.conf', encoding='utf-8')
# config.read('my.conf', encoding='utf-8')


# 检查
has_sec = config.has_section('mysqld')
print(has_sec)

# 添加节点
config.add_section("SEC_1")
# 节点中设置键值
config.set('SEC_1', 'k10', "123")
config.set('SEC_1', 'name', "哈哈哈哈哈")

config.add_section("SEC_2")
config.set('SEC_2', 'k10', "123")
# 内容写入新文件
config.write(open('/Users/wupeiqi/PycharmProjects/luffyCourse/day09/files/xxoo.conf', 'w'))


# 删除节点
config.remove_section("SEC_2")
# 删除节点中的键值
config.remove_option('SEC_1', 'k10')
config.write(open('/Users/wupeiqi/PycharmProjects/luffyCourse/day09/files/new.conf', 'w'))

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 開発では比較的まれに使用されるため、理解として使用できます (後のコースでは、WeChat 決済と WeChat 公式アカウントのメッセージ処理を説明するときに XML ベースのデータ転送を使用します)。

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

[1] ファイルとコンテンツの読み取り

from xml.etree import ElementTree as ET

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

# 获取根标签
root = tree.getroot()

print(root) # <Element 'data' at 0x7f94e02763b0>
from xml.etree import ElementTree as ET

content = """
<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>
"""

root = ET.XML(content)
print(root)  # <Element 'data' at 0x7fdaa019cea0>

【2】ノードデータの読み込み

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>
"""

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

# 获取data标签的孩子标签
for child in root:
    # child.tag = conntry
    # child.attrib = {"name":"Liechtenstein"}
    print(child.tag, child.attrib)
    for node in child:
        print(node.tag, node.attrib, node.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)

for child in root.iter('year'):
    print(child.tag, child.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)
v1 = root.findall('country')
print(v1)

v2 = root.find('country').find('rank')
print(v2.text)

【3】ノードの変更と削除

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', '2020-11-11')
print(rank.text, rank.attrib)
############ 保存文件 ############
tree = ET.ElementTree(root)
tree.write("new.xml", encoding='utf-8')


# 删除节点
root.remove( root.find('country') )
print(root.findall('country'))

############ 保存文件 ############
tree = ET.ElementTree(root)
tree.write("newnew.xml", encoding='utf-8')

[4] 建築関連書類

<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'})

# 在大儿子中创建两个孙子
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('oooo.xml', encoding='utf-8', short_empty_elements=False)
<famliy>
    <son name="儿1">
        <grandson name="儿11"></grandson>
        <grandson name="儿12"></grandson>
    </son>
    <son name="儿2"></son>
</famliy>
from xml.etree import ElementTree as ET

# 创建根节点
root = ET.Element("famliy")


# 创建大儿子
son1 = root.makeelement('son', {
    
    'name': '儿1'})
# 创建小儿子
son2 = root.makeelement('son', {
    
    "name": '儿2'})

# 在大儿子中创建两个孙子
grandson1 = son1.makeelement('grandson', {
    
    'name': '儿11'})
grandson2 = son1.makeelement('grandson', {
    
    'name': '儿12'})

son1.append(grandson1)
son1.append(grandson2)


# 把儿子添加到根节点中
root.append(son1)
root.append(son2)

tree = ET.ElementTree(root)
tree.write('oooo.xml',encoding='utf-8')
<famliy>
	<son name="儿1">
    	<age name="儿11">孙子</age>
    </son>
	<son name="儿2"></son>
</famliy>
from xml.etree import ElementTree as ET


# 创建根节点
root = ET.Element("famliy")


# 创建节点大儿子
son1 = ET.SubElement(root, "son", attrib={
    
    'name': '儿1'})
# 创建小儿子
son2 = ET.SubElement(root, "son", attrib={
    
    "name": "儿2"})

# 在大儿子中创建一个孙子
grandson1 = ET.SubElement(son1, "age", attrib={
    
    'name': '儿11'})
grandson1.text = '孙子'


et = ET.ElementTree(root)  #生成文档对象
et.write("test.xml", encoding="utf-8")
<user><![CDATA[你好呀]]</user>
from xml.etree import ElementTree as ET

# 创建根节点
root = ET.Element("user")
root.text = "<![CDATA[你好呀]]"

et = ET.ElementTree(root)  # 生成文档对象
et.write("test.xml", encoding="utf-8")
  • 場合:
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 ファイルを処理する機能が用意されていないため、Python で Excel を操作したい場合は、サードパーティのモジュールに従う必要があります。

pip install openpyxl

このモジュールは Excel を操作するために Python の関連機能を統合しています。その後、このモジュールが提供する関連機能を学習する必要があります。

[1] Excelを読む(理解するだけ)

  • シートを読む
from openpyxl import load_workbook

wb = load_workbook("files/p1.xlsx")

# sheet相关操作

# 1.获取excel文件中的所有sheet名称

print(wb.sheetnames) # 获取所有的sheet名名称['数据导出', '用户列表', 'Sheet1', 'Sheet2']


# 2.选择sheet,基于sheet名称

sheet = wb["数据导出"]
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)
"""
  • シート内のセルのデータを読み取る
from openpyxl import load_workbook

wb = load_workbook("files/p1.xlsx")
sheet = wb.worksheets[0]

# 1.获取第N行第N列的单元格(位置是从1开始)
"""
cell = sheet.cell(1, 1)

print(cell.value)
print(cell.style)
print(cell.font)
print(cell.alignment)
"""

# 2.获取某个单元格
"""
c1 = sheet["A2"]
print(c1.value)

c2 = sheet['D4']
print(c2.value)
"""

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

# 4.所有行的数据(获取某一列数据)
"""
for row in sheet.rows:
    print(row[0].value, row[1].value)
"""

# 5.获取所有列的数据
"""
for col in sheet.columns:
    print(col[1].value)
"""
  • 結合されたセルを読み取る
from openpyxl import load_workbook

wb = load_workbook("files/p1.xlsx")
sheet = wb.worksheets[2]

# 获取第N行第N列的单元格(位置是从1开始)
c1 = sheet.cell(1, 1)
print(c1)  # <Cell 'Sheet1'.A1>
print(c1.value) # 用户信息

c2 = sheet.cell(1, 2)
print(c2)  # <MergedCell 'Sheet1'.B1>
print(c2.value) # None

from openpyxl import load_workbook

wb = 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>)

[2] Excelを書く

Excelでファイルを書きたい場合、大きく分けて次のようになります。

  • 元の Excel ファイルに基づいてコンテンツを記述します。
from openpyxl import load_workbook

wb = load_workbook('files/p1.xlsx')
sheet = wb.worksheets[0]

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

# 将excel文件保存到p2.xlsx文件中
wb.save("files/p2.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")

Excelの見方と作り方を理解すれば、その後のExcelのシートやセルの操作は基本的に同じです。

from openpyxl import workbook

wb = workbook.Workbook() # Sheet

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

# 2. 创建sheet并设置sheet颜色
"""
sheet = wb.create_sheet("工作计划", 0)
sheet.sheet_properties.tabColor = "1072BA"
wb.save("p2.xlsx")
"""

# 3. 默认打开的sheet
"""
wb.active = 0
wb.save("p2.xlsx")
"""

# 4. 拷贝sheet
"""
sheet = wb.create_sheet("工作计划")
sheet.sheet_properties.tabColor = "1072BA"

new_sheet = wb.copy_worksheet(wb["Sheet"])
new_sheet.title = "新的计划"
wb.save("p2.xlsx")
"""

# 5.删除sheet
"""
del wb["用户列表"]
wb.save('files/p2.xlsx')
"""
from openpyxl import load_workbook
from openpyxl.styles import Alignment, Border, Side, Font, PatternFill, GradientFill


wb = load_workbook('files/p1.xlsx')

sheet = wb.worksheets[1]

# 1. 获取某个单元格,修改值
"""
cell = sheet.cell(1, 1)
cell.value = "开始"
wb.save("p2.xlsx")
"""

# 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 = "新的值"
wb.save("p2.xlsx")
"""

# 4. 对齐方式
"""
cell = sheet.cell(1, 1)

# horizontal,水平方向对齐方式:"general", "left", "center", "right", "fill", "justify", "centerContinuous", "distributed"
# vertical,垂直方向对齐方式:"top", "center", "bottom", "justify", "distributed"
# text_rotation,旋转角度。
# wrap_text,是否自动换行。
cell.alignment = Alignment(horizontal='center', vertical='distributed', text_rotation=45, wrap_text=True)
wb.save("p2.xlsx")
"""

# 5. 边框
# side的style有如下:dashDot','dashDotDot', 'dashed','dotted','double','hair', 'medium', 'mediumDashDot', 'mediumDashDotDot','mediumDashed', 'slantDashDot', 'thick', 'thin'
"""
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  # 左上 ~ 右下
)
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")
"""
"""
sheet.unmerge_cells("B2:D8")
wb.save("p2.xlsx")
"""

# 11.写入公式
"""
sheet = wb.worksheets[3]
sheet["D1"] = "合计"
sheet["D2"] = "=B2*C2"
wb.save("p2.xlsx")
"""
"""
sheet = wb.worksheets[3]
sheet["D3"] = "=SUM(B3,C3)"
wb.save("p2.xlsx")
"""

# 12.删除
"""
# idx,要删除的索引位置
# amount,从索引位置开始要删除的个数(默认为1)
sheet.delete_rows(idx=1, amount=20)
sheet.delete_cols(idx=1, amount=3)
wb.save("p2.xlsx")
"""

# 13.插入
"""
sheet.insert_rows(idx=5, amount=10)
sheet.insert_cols(idx=3, amount=2)
wb.save("p2.xlsx")
"""

# 14.循环写内容
"""
sheet = wb["Sheet"]
cell_range = sheet['A1:C2']
for row in cell_range:
    for cell in row:
        cell.value = "xx"

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")
"""

# 15.移动
"""
# 将H2:J10范围的数据,向右移动15个位置、向上移动1个位置
sheet.move_range("H2:J10",rows=1, cols=15)
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) # 自动翻译公式
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. 压缩文件
"""
# base_name,压缩后的压缩包文件
# format,压缩的格式,例如:"zip", "tar", "gztar", "bztar", or "xztar".
# root_dir,要压缩的文件夹路径
"""
# shutil.make_archive(base_name=r'datafile',format='zip',root_dir=r'files')


# 2. 解压文件
"""
# filename,要解压的压缩包文件
# extract_dir,解压的路径
# format,压缩文件格式
"""
# shutil.unpack_archive(filename=r'datafile.zip', extract_dir=r'xxxxxx/xo', format='zip')

7. パス相関

[1] 逃げる

Windows のパスでは \ が使用され、Linux のパスでは / が使用されます。

特に、Windows システムにそのようなパスがある場合D:\nxxx\txxx\x1、プログラムはエラーを報告します。path には特殊文字\n(改行文字) と(タブ文字) が含まれているため\t、Python インタプリタはそれらを自動的に区別できません。

したがって、Windows でパスを記述する場合、通常は次の 2 つの方法があります。

  • エスケープ文字を追加します。例:"D:\\nxxx\\txxx\\x1"
  • パスの前に r を追加します。例:r"D:\\nxxx\\txxx\\x1"

【2】プログラム電流経路

プロジェクト内で相対パスが使用されている場合は、現在の場所に必ず注意してください。

例:パスの下にファイルを/Users/wupeiqi/PycharmProjects/CodeRepository/書き込みますdemo.py

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

次の 2 つの方法で実行します。

  • 方法 1、ファイルは/Users/wupeiqi/PycharmProjects/CodeRepository/ディレクトリに作成されます。
cd /Users/wupeiqi/PycharmProjects/CodeRepository/
python demo.py
  • 方法 2、ファイルは/Users/wupeiqiディレクトリに作成されます。
cd /Users/wupeiqi
python /Users/wupeiqi/PycharmProjects/CodeRepository/demo.py
import os

"""
# 1.获取当前运行的py脚本所在路径
abs = os.path.abspath(__file__)
print(abs) # /Users/wupeiqi/PycharmProjects/luffyCourse/day09/20.路径相关.py
path = os.path.dirname(abs)
print(path) # /Users/wupeiqi/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)
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('文件路径不存在')

[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')   
print(p1)

p2 = os.path.join(base_path, 'xx', 'oo', 'a1.png')
print(p2)
"""

# 4. 判断路径是否存在
"""
exists = os.path.exists(p1)
print(exists)
"""

# 5. 创建文件夹
"""
os.makedirs(路径)
"""
"""
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) # False,最后一个文件有后缀名,故判断为不是文件夹

folder_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/wupeiqi/Desktop/图/csdn/","/Users/wupeiqi/PycharmProjects/CodeRepository/files")
                    #  要拷贝的文件夹                    拷贝到此处
"""

# 9.拷贝文件
"""
shutil.copy("/Users/wupeiqi/Desktop/图/csdn/[email protected]","/Users/wupeiqi/PycharmProjects/CodeRepository/")
shutil.copy("/Users/wupeiqi/Desktop/图/csdn/[email protected]","/Users/wupeiqi/PycharmProjects/CodeRepository/x.png")
"""

# 10.文件或文件夹重命名
"""
shutil.move("/Users/wupeiqi/PycharmProjects/CodeRepository/x.png","/Users/wupeiqi/PycharmProjects/CodeRepository/xxxx.png")
shutil.move("/Users/wupeiqi/PycharmProjects/CodeRepository/files","/Users/wupeiqi/PycharmProjects/CodeRepository/images")
"""

要約する

  1. ファイルの相対パス。相対パスを使用すると、プログラムのディレクトリが異なる方法で実行され、パスの問題が発生する可能性があります。したがって、相対パスを使用する場合は、現在実行中のプログラムが配置されているディレクトリを必ず把握してください。

  2. 絶対ファイル パス (推奨)。ファイル パスをハードコーディングせず、OS モジュールの関連機能に基づいて絶対パスを自動的に取得するため、プロジェクトを他のファイルまたはコンピュータに移動できます。

   import os
   base_dir = os.path.dirname(os.path.abspath(__file__))
   file_path = os.path.join(base_dir, 'files', 'info.txt')
  1. パスエスケープ

    • 手動でパスを記述する場合は、パスに r または \ を追加して処理する必要があります。
    • os.path.join スプライシングに基づく内部自動処理では、手動処理は必要ありません。
  2. サードパーティのモジュールをダウンロードしてインストールするにはどうすればよいですか?

   pip install 模块名称
  • リクエスト モジュールを使用して、ネットワーク リクエストを送信できます。
  • openpyxl モジュールは Excel 形式のファイルを処理します。

補足的な知識のポイント

# 1.for循环

data_list = [11,22,33,44,55]
for item in data_list:
    print(item)
    break
else:
    print("else中的内容") # for循环中的内容全部执行了一遍,且未遇到break,则会执行else中的内容


# 2.enumerate  循环内容,循环索引

# 方法一(旧方法):
data_list = [11, 22, 33, 44, 55]
for index in range(len(data_list)):
    print(index+1, data_list[index])

# 方法二:
data_list = [11, 22, 33, 44, 55]
for i, item in enumerate(data_list, 1):   #  I从1开始每次加1,i也可以是其他数值
    print(i, item)

# 输出:
1 11
2 22
3 33 
4 44
5 55

手術

  1. csv形式によるユーザー登録&ログイン認証を実現。詳細な要件は次のとおりです。

    • ユーザーが登録するときは、新しく登録したユーザーを csv ファイルに書き込む必要があり、ユーザーは Q または q を入力して終了します。
    • ユーザーがログインすると、csv ファイルのユーザー情報を 1 行ずつ読み取って検証します。
    • ヒント: ファイル パスには、os モジュールによって構築された絶対パスを使用する必要があります。
import os

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

# 用户注册
while True:
    choice = input("是否进行用户注册(Y/N)?")
    choice = choice.upper()
    if choice not in {
    
    'Y', 'N'}:
        print('输入格式错误,请重新输入。')
        continue

    if choice == "N":
        break

    with open(db_file_path, mode='a', encoding='utf-8') as file_object:
        while True:
            user = input("请输入用户名(Q/q退出):")
            if user.upper() == 'Q':
                break
            pwd = input("请输入密码:")
            file_object.write("{},{}\n".format(user, pwd))
            file_object.flush()
    break

# 用户登录
print("欢迎使用xx系统,请登录!")
username = input("请输入用户名:")
password = input("请输入密码:")
if not os.path.exists(db_file_path):
    print("用户文件不存在")
else:
    with open(db_file_path, mode='r', encoding='utf-8') as file_object:
        for line in file_object:
            user, pwd = line.strip().split(',')
            if username == user and pwd == password:
                print('登录成功')
                break
        else:
            print("用户名或密码错误")
"""

  1. 補足コード:指定した地域の気象情報をオンラインで取得し、Excelに書き込みます。
   import requests
   
   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)
       print(res.text)
   
       # 1.提取XML格式中的数据
       # 2.为每个城市创建一个sheet,并将获取的xml格式中的数据写入到excel中。 
import os
import requests
from xml.etree import ElementTree as ET
from openpyxl import workbook

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

# 创建excel且默认会创建一个sheet(名称为Sheet)
wb = workbook.Workbook()
del wb['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)

    # 1.提取XML格式中的数据
    root = ET.XML(res.text)

    # 2.为每个城市创建一个sheet,并将获取的xml格式中的数据写入到excel中。
    sheet = wb.create_sheet(city)

    for row_index, node in enumerate(root, 1):
        text = node.text
        cell = sheet.cell(row_index, 1)
        cell.value = text

wb.save(target_excel_file_path)

  1. 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ファイルを作成し、ノードごとにシートを作成し、ノード配下のキー値を以下の形式でExcelに書き込みます。

    • 最初の行、フォントは白、セルの背景色は青。
    • コンテンツが中央に配置されます。
    • フレーム。
import os
import configparser
from openpyxl import workbook
from openpyxl.styles import Alignment, Border, Side, Font, PatternFill

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

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

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

# 循环获取每个节点,并为每个节点创建一个sheet
for section in config.sections():
    # 在excel中创建一个sheet,名称为ini文件的节点名称
    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 position, text in title_dict.items():
        cell = sheet[position]
        # 设置值
        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, val 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 = val
    #     c2.alignment = align
    #     c2.border = border
    #     row_index += 1

    row_index = 2
    for group in config.items(section):
        # group = ("datadir","/var/lib/mysql")
        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. 以下の機能を実現するためにコードを補足します。
   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)
   
   # 3.在将下载下来的文件解压到 /files/html/ 目录下
import os
import shutil
import requests

# 文件路径处理
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.makedirs(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]
zip_file_path = os.path.join(download_folder, file_name) # .../files/package/HtmlStore.zip
with open(zip_file_path, mode='wb') as file_object:
    file_object.write(res.content)

# 3.在将下载下来的文件解压到 /files/html/ 目录下
unpack_folder = os.path.join(base_dir, 'files', 'html')
shutil.unpack_archive(filename=zip_file_path, extract_dir=unpack_folder, format='zip')

おすすめ

転載: blog.csdn.net/weixin_46268244/article/details/131426029