【自前python講座】標準ライブラリ(ファイル/ディレクトリ/時間操作)

python-standard-lib python
python-standard-lib



自前の python 講座用資料です.
今回は,標準ライブラリの一部について紹介します.

今回のコードは,次の github にも載せています.

https://github.com/KazutoMakino/PythonCourse/blob/main/007_std_libs/007_std_libs.ipynb

Python の標準ライブラリの一覧は,公式ドキュメント (https://docs.python.org/ja/3/library/) の通りで,200 を超えます.
もちろん,全て使うかというとそうではなく,やりたい内容によっては使うものだったり,全く使わないものも出てきます.
さらに,良く使う標準ライブラリにおいても,使ったことが無いようなクラスやメソッドもあり,たまに使うものや使ったことが無いものは,大体調べながらプログラミングするのが常人のレベルと考えます.
従って,今回は,今後プログラミングしていくにあたって「あんな使い方やライブラリがあったな」というヒントや調べるきっかけを提供することを目的として,個人的によく使う標準ライブラリの内,よく使う使い方について紹介します.
といっても,よく使うライブラリも数多くあるので,その中から,以下の,特に良く使っているライブラリについて記載することとします.
以下で紹介しないライブラリについては,必要に応じて参照ください.


特に良く使っている標準ライブラリ(この記事にて紹介):


良く使っている標準ライブラリ:

たまに使う標準ライブラリ:

あまり使わない標準ライブラリ・・・・それ以外は省略

ライブラリやモジュールの呼び出し方法

例えば C 言語では,標準入出力関数のヘッダファイル stdio.h#include <stdio.h> にてインクルードした場合には,stdio.h にて定義されている printf やら scanf などその他もろもろの型/定義/関数/マクロなどがいきなり使えるようになりますが,例えば printf など使いたい定義について stdio.h に内包されていることを知っている必要があります.
しかし,python ではその心配はありません.
import によって宣言されたモジュールの関数やクラスを参照するためには,このモジュールの名前が出てくるため,「ある特定の関数がどの宣言と紐づいているか分からなくなる」ということがなくなります.
個人的に,至極納得のいく言語仕様です.
(余談ですが,C 言語にて #include <stdio.h> とすると,stdio.h 内のマクロなどが呼び出されますが,その内の一つの stdout の中身に printf があるため,printf が使えるようになります (参考: http://www.c-lang.org/detail/stdio_h.html ).これが,初学者に苦し紛れで教えられるような「おまじない」の本質です.)

ライブラリやモジュールは,次のような構文で呼び出します.

import モジュール as 代替する使用したい名前
 または,
import モジュール.モジュールの関数やクラス as 代替する使用したい名前
 または,
from モジュール import モジュールの関数やクラス as 代替する使用したい名前

上記の as 以降はあってもなくても良く,モジュール名などを省略名称で用いたい時に使います.
import されたモジュールは以下のように用います.

モジュール(または as で定義した名前).そのクラスや関数

このように,モジュール名とその中身をドット “.” でつなげるだけです.
とはいっても,日本語で書くと良く分からないと思うので,以下,紹介とともに例を挙げていきます.

pathlib

pathlib (https://docs.python.org/ja/3/library/pathlib.html) は,ファイル/ディレクトリパスを扱う標準ライブラリです.
一般的なファイル操作全般に対して用いています.
pathlib は Path クラスとそのメソッドを用いることがほとんどです.
以下に import と基本的な使い方について紹介します.

from pathlib import Path

Path(パス文字列) というように,Path クラスにパス文字列を渡して各種メソッドを適用していきます.
例えば,今のディレクトリパス “./” を指定すると,

pwd = Path("./")
pwd

# WindowsPath('.')
type(pwd)

# pathlib.WindowsPath

というように,相対パスが得られます.
実行環境が windows なので,pathlib.WindowsPath 型となっています.
絶対パスは,resolve メソッドで得ることができます.

pwd.resolve()

# WindowsPath('C:/Users/_____/Documents/code/PythonCourse/007_std_libs')

新しくファイルを作成するときは,touch メソッドを用います.

new_item = Path("./new_item.txt")
new_item.touch()

指定したパスが存在するかどうかは,exists メソッドで確認できます.

new_item.exists()

# True

新しくディレクトリを作成するときは,mkdir メソッドを用います.

new_dir = Path("./new_dir")
new_dir.mkdir()
new_dir.exists()

# True

以下のようにもう一度作成しようとすると,FileExistsError が出ます.

new_dir.mkdir()
# ---------------------------------------------------------------------------
# FileExistsError                           Traceback (most recent call last)
# ~\AppData\Local\Temp/ipykernel_12160/3877270268.py in <module>
# ----> 1 new_dir.mkdir()
# 
# ~\AppData\Local\Programs\Python\Python38\lib\pathlib.py in mkdir(self, mode, parents, exist_ok)
#    1286             self._raise_closed()
#    1287         try:
# -> 1288             self._accessor.mkdir(self, mode)
#    1289         except FileNotFoundError:
#    1290             if not parents or self.parent == self:
# 
# FileExistsError: [WinError 183] 既に存在するファイルを作成することはできません。: 'new_dir'

上書きしても良い場合は,引数 exist_ok に True を渡します.

new_dir.mkdir(exist_ok=True)

実は touch メソッドも引数 exist_ok があるのですが,デフォルトが True となっているため,省略してもエラーがでません(逆に,exist_ok=False を指定すると,FileExistsError が出ます).
この場合,空のファイルで上書きされるのではなく,単に更新日時が上書きされるだけです.

mkdir において,デフォルトが False である引数 parents に True を渡すことで,複数階層を同時に作成することができます.

new_dir123 = Path("./new_dir1/new_dir2/new_dir3")
new_dir123.mkdir()
# ---------------------------------------------------------------------------
# FileNotFoundError                         Traceback (most recent call last)
# ~\AppData\Local\Temp/ipykernel_12160/1949577686.py in <module>
#       1 new_dir123 = Path("./new_dir1/new_dir2/new_dir3")
# ----> 2 new_dir123.mkdir()
# 
# ~\AppData\Local\Programs\Python\Python38\lib\pathlib.py in mkdir(self, mode, parents, exist_ok)
#    1286             self._raise_closed()
#    1287         try:
# -> 1288             self._accessor.mkdir(self, mode)
#    1289         except FileNotFoundError:
#    1290             if not parents or self.parent == self:
# 
# FileNotFoundError: [WinError 3] 指定されたパスが見つかりません。: 'new_dir1\\new_dir2\\new_dir3'
new_dir123.mkdir(parents=True)
new_dir123.exists()

# True

指定したパスがファイルかどうかの判定には is_file メソッド,ディレクトリかどうかの判定には is_dir メソッドにて調べることができます.

new_item.is_file(), new_item.is_dir(), new_dir.is_file(), new_dir.is_dir()

# (True, False, False, True)

文字列型の結合は + によって可能ですが,パスの結合は階層を表す / によって結合ができます.

Path("./new_dir1") / Path("new_dir2")

# WindowsPath('new_dir1/new_dir2')

上記でもできますが,先頭の型が pathlib.Path 型であれば,次のように,先頭以外は文字列で結合が可能です.

Path("./new_dir1") / "new_dir2"

# WindowsPath('new_dir1/new_dir2')

階層を区切りたくないけど変数を使ってパス合体させたいという場合は,str() を用いて一旦文字列型にキャストするか,もしくは,f-string を用います.

file_name = "new_item2"
file_path = Path("./new_dir1") / f"new_dir2/{file_name}.txt"
file_path, file_path.exists()

# (WindowsPath('new_dir1/new_dir2/new_item2.txt'), False)

touch はそのファイルを置くディレクトリが存在していれば,複数階層をまたいでも使うことができます.

file_path.touch()
file_path.exists()

# True

指定した階層において,ファイル/ディレクトリの一覧を取得したい場合は,iterdir メソッドにてジェネレータを取得でき,list などで展開できます.

list(pwd.iterdir())

# [WindowsPath('.ipynb_checkpoints'),
#  WindowsPath('007_std_libs.ipynb'),
#  WindowsPath('answer.ipynb'),
#  WindowsPath('new_dir'),
#  WindowsPath('new_dir1'),
#  WindowsPath('new_item.txt')]

また,パスにワイルドカード * (アスタリスク)が指定できる glob メソッドでも調べることができます.

list(pwd.glob("*"))

# [WindowsPath('.ipynb_checkpoints'),
#  WindowsPath('007_std_libs.ipynb'),
#  WindowsPath('answer.ipynb'),
#  WindowsPath('new_dir'),
#  WindowsPath('new_dir1'),
#  WindowsPath('new_item.txt')]

glob メソッドの中の文字列の工夫次第で,検索するオブジェクトを指定することができます.
例えば,.txt ファイルだけにしたい場合は,

list(pwd.glob("*.txt"))

# [WindowsPath('new_item.txt')]

のようにすれば,この階層における探索は可能です.
しかし,先ほど生成した new_dir1/new_dir2/new_item2.txt のパスは上記では得られません.
このパスを得るためには,再帰的に調べさせる必要があり,ワイルドカードを二つと階層を表す / 用いて,例えば以下のように書くことができます.

list(pwd.glob("**/*.txt"))

# [WindowsPath('new_item.txt'), WindowsPath('new_dir1/new_dir2/new_item2.txt')]

ファイルの削除には unlink メソッド,ディレクトリの削除には rmdir メソッドを用います.
ただし,上記で指定したパスが存在しない場合は,FileExistsError が返されます.

new_item

# WindowsPath('new_item.txt')
new_item.unlink()
new_item.exists()

# False
new_dir

# WindowsPath('new_dir')
new_dir.rmdir()
new_dir.exists()

# False
new_dir123

# WindowsPath('new_dir1/new_dir2/new_dir3')

注意として,rmdir は指定したパスのディレクトリが空でないと,OSError が返されます.

Path("new_dir1").rmdir()
# ---------------------------------------------------------------------------
# OSError                                   Traceback (most recent call last)
# ~\AppData\Local\Temp/ipykernel_12160/161957861.py in <module>
# ----> 1 Path("new_dir1").rmdir()
# 
# ~\AppData\Local\Programs\Python\Python38\lib\pathlib.py in rmdir(self)
#    1334         if self._closed:
#    1335             self._raise_closed()
# -> 1336         self._accessor.rmdir(self)
#    1337 
#    1338     def lstat(self):
# 
# OSError: [WinError 145] ディレクトリが空ではありません。: 'new_dir1'
new_dir123.rmdir()
new_dir123.exists()

# False

今まで,ファイルの読み書きは open 関数を用いていましたが,pathlib.Path 型に対しては open メソッドを用いることができます.

test_path = Path("./test.txt")
text = "test"
​
# write
with test_path.open(mode="w") as f:
    f.write(text)
​
# read
with test_path.open(mode="r") as f:
    print(f.read())

# test

一応,pathlib を用いない場合は以下のように書きます.

test_path = "./test.txt"
text = "test"
​
# write
with open(test_path, mode="w") as f:
    f.write(text)
​
# read
with open(test_path, mode="r") as f:
    print(f.read())

# test

windows の環境では pathlib.Path 型のパスを文字列型にすると,人によっては見慣れない形式で出力されます.

str(new_dir123)

# 'new_dir1\\new_dir2\\new_dir3'

これは,windows のパスの区切りが円マーク(バックスラッシュ)であることに起因し,バックスラッシュはエスケープシーケンスであるため,バックスラッシュを出力させるためにはもう一つバックスラッシュがその前に必要になるからです.
上記の例で,もし,バックスラッシュが一つであれば,\ と n で改行してしまいますが,2つ連続しているため,以下のように printf で出力しても \ が残っています.

print(str(new_dir123))

# new_dir1\new_dir2\new_dir3

パスの区切りは OS に依存するため,標準ライブラリの os モジュールによって柔軟に変換することができます.
パスの区切りは os モジュールの sep で参照できます.

import os
​
os.sep

# '\\'

もし,パスの階層の区切りを / にしたい場合は,文字列型にして replace します.

str(new_dir123).replace(os.sep, "/")

# 'new_dir1/new_dir2/new_dir3'

os モジュールも色々使い方があるのですが,今回は割愛いたします.

rmdir では中にファイルやディレクトリがあると削除できませんでしたが,中にあるファイルやディレクトリごと削除したい場合は,次の shutil.rmtree を用います.

shutil

shutil (https://docs.python.org/ja/3/library/shutil.html) は,ファイルの移動やコピー,圧縮/展開などの操作を行う標準ライブラリです.
このライブラリも,多くのファイル操作で役立ちます.

import shutil

実験する前に,今のディレクトリ構成を可視化してみます.

sorted(pwd.glob("./**/*"))

# [WindowsPath('.ipynb_checkpoints'),
#  WindowsPath('.ipynb_checkpoints/007_std_libs-checkpoint.ipynb'),
#  WindowsPath('.ipynb_checkpoints/answer-checkpoint.ipynb'),
#  WindowsPath('007_std_libs.ipynb'),
#  WindowsPath('answer.ipynb'),
#  WindowsPath('new_dir1'),
#  WindowsPath('new_dir1/new_dir2'),
#  WindowsPath('new_dir1/new_dir2/new_item2.txt'),
#  WindowsPath('test.txt')]

test.txtnew_dir1 に移動してみます.
ファイルやディレクトリの移動には shutil.move(src=移動元パス, dst=移動先パス) を用います.

shutil.move(src="./test.txt", dst="./new_dir1")
sorted(pwd.glob("./**/*"))

# [WindowsPath('.ipynb_checkpoints'),
#  WindowsPath('.ipynb_checkpoints/007_std_libs-checkpoint.ipynb'),
#  WindowsPath('.ipynb_checkpoints/answer-checkpoint.ipynb'),
#  WindowsPath('007_std_libs.ipynb'),
#  WindowsPath('answer.ipynb'),
#  WindowsPath('new_dir1'),
#  WindowsPath('new_dir1/new_dir2'),
#  WindowsPath('new_dir1/new_dir2/new_item2.txt'),
#  WindowsPath('new_dir1/test.txt')]

上記の例において,引数 dst にはディレクトリパスを与えましたが,ファイルパスを与えた場合は,ファイル移動後にそのファイル名にて名前が変更されます.

コピーは shutil.copy(src=移動元パス, dst=移動先パス) でできます.
今度は,今移動した new_dir1/test.txt をこの階層にコピーしてみます.

shutil.copy(src="new_dir1/test.txt", dst=".")
sorted(pwd.glob("**/*"))

# [WindowsPath('.ipynb_checkpoints'),
#  WindowsPath('.ipynb_checkpoints/007_std_libs-checkpoint.ipynb'),
#  WindowsPath('.ipynb_checkpoints/answer-checkpoint.ipynb'),
#  WindowsPath('007_std_libs.ipynb'),
#  WindowsPath('answer.ipynb'),
#  WindowsPath('new_dir1'),
#  WindowsPath('new_dir1/new_dir2'),
#  WindowsPath('new_dir1/new_dir2/new_item2.txt'),
#  WindowsPath('new_dir1/test.txt'),
#  WindowsPath('test.txt')]

ディレクトリの圧縮は,

shutil.make_archive(
    base_name=拡張子なしの作成するファイルパス,
    format=zip などの圧縮ファイルの拡張子の文字列,
    root_dir=圧縮させる対象のディレクトリパス,
)

でできます.
format は “zip” 以外にも,”tar”, “gztar”, “bztar”, “xztar” を用いることができます.
試しに,new_dir1 以下の階層を zip で圧縮して,この階層に保存してみましょう.

shutil.make_archive(
    base_name="new_dir1", format="zip", root_dir="new_dir1"
)
sorted(pwd.glob("**/*"))

# [WindowsPath('.ipynb_checkpoints'),
#  WindowsPath('.ipynb_checkpoints/007_std_libs-checkpoint.ipynb'),
#  WindowsPath('.ipynb_checkpoints/answer-checkpoint.ipynb'),
#  WindowsPath('007_std_libs.ipynb'),
#  WindowsPath('answer.ipynb'),
#  WindowsPath('new_dir1'),
#  WindowsPath('new_dir1/new_dir2'),
#  WindowsPath('new_dir1/new_dir2/new_item2.txt'),
#  WindowsPath('new_dir1/test.txt'),
#  WindowsPath('new_dir1.zip'),
#  WindowsPath('test.txt')]

圧縮ファイルの展開は,

shutil.unpack_archive(
    filename=圧縮ファイルパス,
    extract_dir=展開するディレクトリパス
)

でできます.
new_dir1.zip をここに展開すると元のフォルダと被るので,別に unpack という名前のディレクトリを作って,そこに new_dir1.zip を入れ,その中で展開してみます.

Path("unpack").mkdir()
shutil.move(src="new_dir1.zip", dst="unpack/")
sorted(pwd.glob("**/*"))

# [WindowsPath('.ipynb_checkpoints'),
#  WindowsPath('.ipynb_checkpoints/007_std_libs-checkpoint.ipynb'),
#  WindowsPath('.ipynb_checkpoints/answer-checkpoint.ipynb'),
#  WindowsPath('007_std_libs.ipynb'),
#  WindowsPath('answer.ipynb'),
#  WindowsPath('new_dir1'),
#  WindowsPath('new_dir1/new_dir2'),
#  WindowsPath('new_dir1/new_dir2/new_item2.txt'),
#  WindowsPath('new_dir1/test.txt'),
#  WindowsPath('test.txt'),
#  WindowsPath('unpack'),
#  WindowsPath('unpack/new_dir1.zip')]
shutil.unpack_archive(
    filename="unpack/new_dir1.zip", extract_dir="unpack/"
)
sorted(pwd.glob("**/*"))

# [WindowsPath('.ipynb_checkpoints'),
#  WindowsPath('.ipynb_checkpoints/007_std_libs-checkpoint.ipynb'),
#  WindowsPath('.ipynb_checkpoints/answer-checkpoint.ipynb'),
#  WindowsPath('007_std_libs.ipynb'),
#  WindowsPath('answer.ipynb'),
#  WindowsPath('new_dir1'),
#  WindowsPath('new_dir1/new_dir2'),
#  WindowsPath('new_dir1/new_dir2/new_item2.txt'),
#  WindowsPath('new_dir1/test.txt'),
#  WindowsPath('test.txt'),
#  WindowsPath('unpack'),
#  WindowsPath('unpack/new_dir1.zip'),
#  WindowsPath('unpack/new_dir2'),
#  WindowsPath('unpack/new_dir2/new_item2.txt'),
#  WindowsPath('unpack/test.txt')]

shutil.rmtree(path=ディレクトリパス) とすることにより,指定したディレクトリよりも下層のファイル/ディレクトリ含め全て根こそぎ削除することができます.

shutil.rmtree(path="unpack")
sorted(pwd.glob("**/*"))

# [WindowsPath('.ipynb_checkpoints'),
#  WindowsPath('.ipynb_checkpoints/007_std_libs-checkpoint.ipynb'),
#  WindowsPath('.ipynb_checkpoints/answer-checkpoint.ipynb'),
#  WindowsPath('007_std_libs.ipynb'),
#  WindowsPath('answer.ipynb'),
#  WindowsPath('new_dir1'),
#  WindowsPath('new_dir1/new_dir2'),
#  WindowsPath('new_dir1/new_dir2/new_item2.txt'),
#  WindowsPath('new_dir1/test.txt'),
#  WindowsPath('test.txt')]

time

time (https://docs.python.org/ja/3/library/time.html) は,時間計測などを行う標準ライブラリです.
一定時間処理を止めたいときや処理の時間を計測するときに用います.

import time

一定時間処理を止めたいときは,time.sleep(止めたい秒数) を実行します.
秒数は,float でも指定が可能です.

print("start")
for i in range(5):
    time.sleep(1)
    print(i+1)
print("end")

# start
# 1
# 2
# 3
# 4
# 5
# end

プログラムがスタートしてから今までの経過時間について,色んな方法があるのですが,精度などを考慮すると個人的なおすすめは,time.perf_counter() を用いて取得する方法です.
これにより,正確な時間が 0.1 マイクロ秒オーダーまで取得することが可能です.

time.perf_counter()

# 118.5410032
time.perf_counter()

# 118.5596373

プログラムスタートしてからの経過時間であるため,ある処理の塊についての時間を測定したい場合には,次のように処理の前の tstart = time.perf_counter() のように変数に代入しておき,経過時間算出時に time.perf_counter() - tstart とすることで,経過時間を取得することができます.

tstart = time.perf_counter()
time.sleep(1)
telpsd = time.perf_counter() - tstart
telpsd

# 1.0034763999999967

datetime

datetime (https://docs.python.org/ja/3/library/datetime.html) は,日付/時差取得などを行う標準ライブラリです.
datetime はこの中の datetime オブジェクトを用いることがほとんどですので,以下のように import してしまうことが多いです.

from datetime import datetime

現在の日付と時刻は datetime.now(タイムゾーン) にて取得できます.
引数のタイムゾーンは,初期値が None であり,この場合はシステムのタイムゾーンが適用されます.

datetime.now()

# datetime.datetime(2022, 2, 11, 1, 12, 18, 950631)

左から順に,年,月,日,時,分,秒,サブ秒 です.
これの type は,

type(datetime.now())

# datetime.datetime

ということで,datetime.datetime です.
タイムゾーンを気にしなければならないケースとして,例えば,世界で個々に同時でデータを取得して,個々のシステムに依存したタイムゾーンで時間の情報を保存されているときに,どこかの時刻で統一して考えたほうが良い場合もあります.
datetime.datetime 型変数に関しては,tzinfo にてタイムゾーンがわかります(以下は,戻り値が None で出力されないため,あえて print を用いて表示しています).

print(datetime.now().tzinfo)

# None

タイムゾーンをあわせたい場合,世界標準時(UTC)にする,または,世界標準時から何時間プラス/マイナスで書くことが多いです.
タイムゾーンを UTC に指定する場合は,datetime ライブラリの timezone オブジェクトが使えます.

from datetime import timezone

これを用いて UTC にしたい場合は,違いを見せるために一緒に日本の時刻も取得すると,

ja_time = datetime.now()
utc_time = datetime.now(timezone.utc)
​
print(f"japan: {ja_time}")
print(f"utc: {utc_time}")

# japan: 2022-02-11 01:12:19.042634
# utc: 2022-02-10 16:12:19.042634+00:00

ということで,ご存知のとおり世界標準時より日本は 9 時間進んでいます.
取得時刻がシステムに影響させないようにするためには上記 timezone.utc を指定した時刻に時差分を足し引きしましょう(サードパーティライブラリの pytz を用いてタイムゾーンを指定することもできます).

datetime.datetime 型同士は引き算が可能です.

tstart = datetime.now()
time.sleep(1)
telapsed = datetime.now() - tstart
telapsed

# datetime.timedelta(seconds=1, microseconds=7944)

このとおり,datetime.datetime 型同士の引き算は datetime.timedelta 型になります.
この時間の差分について,float の秒数で取得したくなることが多いと思うのですが,その変換は datetime.timedelta 型変数に対して total_seconds() メソッドを用いることにより取得できます.

telapsed.total_seconds()

# 1.007944
type(telapsed.total_seconds())

# float

datetime.datetime オブジェクトについてもこのまま用いるのではなく,文字列のタイムスタンプにして,例えばファイル名や時系列データの索引として用いることがあると思います.
このように,指定した文字列に変換するためには,

datetime型変数.strftime(書式指定子)

という風に, srtftime メソッドを用います.
引数の書式指定子は,公式ドキュメント (https://docs.python.org/ja/3/library/datetime.html) から良く使うものを以下に抜粋します.

指定子意味使用例
%aロケールの短縮系の曜日名Sun, Mon, …, Sat
%Aロケールの曜日名Sunday, Monday, …, Saturday
%d0 埋めした 10 進数で表記した日にち01, 02, …, 31
%m0 埋めした 10 進数で表記した月01, 02, …, 12
%Y西暦を表示1900, 1901, …, 2022, …
%H0 埋めした 10 進数で表記した 24 時間表記の時間00, 01, …, 23
%M0 埋めした 10 進数で表記した分00, 01, …, 59
%S0 埋めした 10 進数で表記した秒00, 01, …, 59
%fマイクロ秒000000, 000001, …, 999999
%Zタイムゾーンの名前UTC, GMT, …
Table of datetime

例えば,取得した時間を文字列のタイムスタンプとして用いることを想定すると,

date_str = datetime.now().strftime("%Y%m%d%H%M%S%f")
date_str

# '20220211011221540247'

という風にでき,これを例えばファイル名などに用いることができます.

逆に,

datetime.strptime(日付を表す文字列, 書式指定子)

を用いることにより,文字列から datetime.datetime 型にも変換できます.

datetime.strptime(date_str, "%Y%m%d%H%M%S%f")

# datetime.datetime(2022, 2, 11, 1, 12, 21, 540247)

シチュエーションとしては,タイムスタンプから時間差を逆算する際に用いる場合が想定されます.

今回は,ファイル/ディレクトリ操作といったパス周りだったり,時間を扱う標準ライブラリを主に紹介しました.
他にも,乱数を扱う random だったり,数学関数を扱う math,統計関数を扱う statistics,または,csv ファイルの入出力に有益な csv といった標準ライブラリがありますが,これらを使わずに優秀なサードパーティライブラリを使うことが多いので割愛します.
上記のサードパーティライブラリについては,また他の記事に記載いたします.

演習問題

Q1. 日時を表す 2 つの文字列 "2038/01/19-03:14:07.000000", "2045/01/01-00:00:00.000000" について時間の差を秒で出力してください.

sorted(Path("./").iterdir())

# [WindowsPath('.ipynb_checkpoints'),
#  WindowsPath('007_std_libs.ipynb'),
#  WindowsPath('answer.ipynb'),
#  WindowsPath('new_dir1'),
#  WindowsPath('test.txt')]

Q2. 上記のように new_dir1test.txt がこのディレクトリに残ったままなので,これら二つをプログラミングで削除しましょう(エクスプローラーから削除しないでくださいね).
Q3. このファイルはいつ開きましたか? datetime.datetime 型にて教えてください.

Q1.

from datetime import datetime

fmt = "%Y/%m/%d-%H:%M:%S.%f"
t1 = datetime.strptime("2038/01/19-03:14:07.000000", fmt)
t2 = datetime.strptime("2045/01/01-00:00:00.000000", fmt)
​
(t2 - t1).total_seconds()

# 219357953.0

Q2.

import shutil
​
shutil.rmtree("./new_dir1")
Path("./test.txt").unlink()
​
sorted(Path("./").iterdir())

# [WindowsPath('.ipynb_checkpoints'),
#  WindowsPath('007_std_libs.ipynb'),
#  WindowsPath('answer.ipynb')]

Q3.

import time
from datetime import datetime, timedelta
​
datetime.now() - timedelta(seconds=time.perf_counter())

# datetime.datetime(2022, 2, 11, 1, 8, 2, 30912)

Python のおすすめの学習方法

プログラミングを最短で習得する,少なくても自分の意志で使えるようになる方法について,いくつかプログラミング言語を触ってきた筆者としては何の言語においても,以下2点が重要だと思います.

  • 元々自分が他の言語で作っていた処理を違う言語で書き直す・・・・英語を勉強するときも,脳を生まれたばかりのまっさらな状態から勉強するわけではなく,日本語を通したり対比して,学習済みの言語野を用いて勉強するのと似ています
  • 言語自体を網羅的に勉強するのではなく,やりたい事を先に考え,それを達成するために色々と調べながら実装する・・・・例えば,留学で語学力が上達するのは,その国の言葉を使ってコミュニケーションを取ることが強制されるためであり,使うことに対するモチベーションが一番大事です

独学で行うには,やはり2点目の「やりたい事ドリブン学習」が効果的で,例えば次の書籍は,Python を流行らせている AI/データ分析/機械学習/深層学習について実装することに主眼を置き説明されているので,実際に手を動かしながら学んでいける本だと思います(筆者も最初にこちらの書籍で遊びながら学びました).

コメント

タイトルとURLをコピーしました