1
0

More than 3 years have passed since last update.

ライブラリにある関数を拡張する試行 (pathlibにcopy関数を追加拡張)

Last updated at Posted at 2020-12-30

ライブラリにある関数を拡張します。拡張は、Pythonのクラスに、関数を登録するような形。(クラス下の変数に代入する形、毎回そのクラスから生成されるインスタンスは同じ関数を持つようになる)

以下、例として、pathlibの操作方法を拡張したコード。本来はないファイルコピー・フォルダツリーコピーの関数等を拡張追加します。

拡張試行項目:

  • 拡張1 : 本来はないファイルサイズ取得のsize関数を拡張追加
    • pathlib.Path("...ファイル...").size()
  • 拡張2 : 本来はないフォルダコピーのcopy関数を拡張追加
    • pathlib.Path("...フォルダ...").copy("./test2")
  • 拡張3 : 本来はないフォルダ削除のunlink関数を拡張追加
    • pathlib.Path("...フォルダ...").unlink()
  • 拡張4 : 本来はないファイルコピーのcopy関数を拡張追加
    • pathlib.Path("...ファイル...").copy("./test2.txt")
  • 拡張5 : 本来のファイル削除のunlink関数も機能するか確認
    • pathlib.Path("...ファイル...").unlink()
  • 拡張6 : 「/」の他に「+」でもパスを連結する拡張を追加
    • pathlib.Path("...フォルダ...") + "in1" + "in2" + "test3.txt"
trial.py

# -*- coding: utf-8 -*-

# ライブラリにある関数を拡張する試行、pathlibの操作方法を拡張してみる

import pathlib
import shutil

# sec: main

def main():

    # sec: テストデータ準備

    pathlib.Path("./test/in1/in2").mkdir(parents=True, exist_ok=True)
    pathlib.Path("./test/test.txt").write_text("0123456789")

    # sec: 拡張1 : 本来はないファイルサイズ取得のsize関数を拡張追加

    path_1 = pathlib.Path("./test/test.txt")
    print("size関数を拡張追加:", path_1.size())

    # sec: 拡張2 : 本来はないフォルダコピーのcopy関数を拡張追加

    path_1 = pathlib.Path("./test")
    path_2 = path_1.copy("./test2")
    input("フォルダtest2が作成されたか確認: 停止中")

    # sec: 拡張3 : 本来はないフォルダ削除のunlink関数を拡張追加

    path_2.unlink()
    input("フォルダtest2が削除されたか確認: 停止中")

    # sec: 拡張4 : 本来はないファイルコピーのcopy関数を拡張追加

    path_1 = pathlib.Path("./test/test.txt")
    path_2 = path_1.copy("./test2.txt")
    input("ファイルtest2.txtが作成されたか確認: 停止中")

    # sec: 拡張5 : 本来のファイル削除のunlink関数も機能するか確認

    path_2.unlink()
    input("ファイルtest2.txtが削除されたか確認: 停止中")

    # sec: 拡張6 : 「/」の他に「+」でもパスを連結する拡張を追加

    path_1 = pathlib.Path("./test/test.txt")
    path_2 = path_1.parent + "in1" + "in2" + "test3.txt"
    print("「+」でもパスを連結:", path_2)

"""コンソール出力例:
size関数を拡張追加: 10
ファイルtest2.txtが作成されたか確認: 停止中
ファイルtest2.txtが削除されたか確認: 停止中
フォルダtest2が作成されたか確認: 停止中
フォルダtest2が削除されたか確認: 停止中
「+」でもパスを連結: test\in1\in2\test3.txt
"""

# sec: 拡張

# ファイルサイズ取得
pathlib.Path.size = lambda self: self.stat().st_size # 拡張追加

# ファイルコピー・フォルダツリーコピー
def pathlib_Path_copy_ex(self, path_to):
    if self.is_file():
        shutil.copy(str(self), str(path_to))
    elif self.is_dir():
        shutil.copytree(str(self), str(path_to))
    return pathlib.Path(path_to)
pathlib.Path.copy = pathlib_Path_copy_ex # 拡張追加

# ファイル削除・フォルダツリー削除
def pathlib_Path_unlink_ex(self, *args, **argkv):
    if self.is_file():
        pathlib_Path_unlink_orig(self, *args, **argkv)
    elif self.is_dir():
        shutil.rmtree(str(self))
pathlib_Path_unlink_orig = pathlib.Path.unlink # 元の関数を保持用
pathlib.Path.unlink = pathlib_Path_unlink_ex # 拡張追加

# 「+」でパスを連結
pathlib.Path.__add__ = lambda a, b: a / b # 拡張追加

# sec: entry

if __name__ == "__main__": main()

Python開発の皆様...

ライブラリpathlibに、このファイルコピー・フォルダツリーコピーを行うcopy関数が標準であると便利かなと思っております...

  • 拡張2 : 本来はないフォルダコピーのcopy関数を拡張追加
    • pathlib.Path("...フォルダ...").copy("./test2")
  • 拡張4 : 本来はないファイルコピーのcopy関数を拡張追加
    • pathlib.Path("...ファイル...").copy("./test2.txt")
1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0