====== Python ====== C#で作成したものをPythonに移植する上で調査したメモ\\ Visual Studio 2022を使用するも、途中で拡張機能が充実しているVisual Studio Codeに変更した。 ===== Visual Studio関連 ===== ==== Visual Studio上でUTF-8にして保存したい ===== Visual StudioでPythonファイルを保存するとShift-JISになりデバッグエラーになってしまう。\\ UTF-8で保存できるようにしたい。 * EditorConfig ファイルをプロジェクトに追加する * EditorConfig ファイルの下記内容を記載 root = true [*.py] charset = utf-8 * [[https://docs.microsoft.com/ja-jp/visualstudio/ide/create-portable-custom-editor-options?view=vs-2022|EditorConfig で移植可能なカスタム エディター設定を作成する]] * [[https://ja.stackoverflow.com/questions/85311/visual-studio-2022%E3%81%A7python%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%81%AE%E6%96%87%E5%AD%97%E3%82%B3%E3%83%BC%E3%83%89%E3%82%92utf-8%E3%81%AB%E3%81%99%E3%82%8B%E6%96%B9%E6%B3%95%E3%82%92%E6%95%99%E3%81%88%E3%81%A6%E3%81%8F%E3%81%A0%E3%81%95%E3%81%84|Visual Studio 2022でPythonファイルの文字コードをUTF-8にする方法を教えてください。]] ==== Visual Studioのエディターで行番号を表示する ==== Pythonはエラーに行番号が出てくるので表示するようにしておく。 [[https://docs.microsoft.com/ja-jp/visualstudio/ide/reference/how-to-display-line-numbers-in-the-editor?view=vs-2022|エディターで行番号を表示する]] ===== Visual Studio Code関連 ===== ==== 環境構築 ==== * [[https://www.kkaneko.jp/tools/win/vscodepro.html|Visual Studio Code で Python プログラミング(Windows 上)]] * [[https://note.kiriukun.com/entry/20220226-creating-python-project-with-windows-and-vscode-pipenv|Windows + VSCode + pipenv でPythonの開発環境を作る]] ==== 拡張機能 ==== [[https://yurupro.cloud/767/|【2022年最新版】VSCodeをPython超特化型にする、最高の拡張機能20選まとめ。 【VisualStudio Code】【プラグイン】]] 下記の拡張機能をインストール * indent-rainbow * ZenKaku * Trailing Spaces * Python Indent * Python Docstring Generator ===== コーディング関連 ===== ==== コーディング規約 ==== PEP(Python Enhancement Proposal)の中で、PEP 8は「Style Guide for Python Code」と銘打ち、Pythonのコードを記述する際の基本的なコーディングスタイルを定めている。 * [[https://qiita.com/naomi7325/items/4eb1d2a40277361e898b|Python命名規則一覧]] * [[https://atmarkit.itmedia.co.jp/ait/articles/1912/10/news045.html|[Python入門]Pythonコーディングスタイルガイド]] ==== main関数の書き方 ==== Pythonはスクリプトなのでmain関数を定義する必要はありません。慣例的にmain関数を定義することがあります。 import sys def main(argv): print('Hello, World!') return 0 if __name__ == '__main__': sys.exit(main(sys.argv)) [[https://yu-nix.com/blog/2021/6/25/python-main/|Pythonのmain関数の書き方をわかりやすく解説]] ==== fromやimportの基礎 ==== [[https://techacademy.jp/magazine/23818|Pythonのfromやimportの基礎を現役エンジニアが解説【初心者向け】]] ==== コメント記載方法 ==== Google Styleを採用 [[https://zenn.dev/sasano8/scraps/806b614ca8f640|Python docstringについて]] def func_google(param1, param2): """Summary line. Extended description of function. Args: param1 (int): Description of param1 param2 (str): Description of param2 Returns: bool: Description of return value """ return True ==== 定義変数 ==== Python には、C/C++ の const のような、定数を定義するためのキーワードは用意されていません。 Constクラスを作成して、その中でメンバ変数として定義する。重複定義とか気にせず単純にした。\\ 定義変数は、英大文字を使用する。\\ * [[https://qiita.com/nadu_festival/items/c507542c11fc0ff32529|Pythonで定数を宣言したい(n+1番煎じ)]] * [[https://maku77.github.io/python/syntax/const.html|Python で定数を定義する]] class Const(): # クラス変数として定数を定義する FOO = 1 BAR = "TEST" 使用方法 From Const import Const a = Const.Foo ==== 文字列の囲み ==== Python では、単一引用符 ' で囲まれた文字列と、二重引用符 " で囲まれた文字列は同じです。\\ PEP 8では、どちらを推奨するかの立場は示しません。 C#からの移植なので、二重引用符(ダブルクォーテーション)をベースとする。 === 文字列の長さ取得 === C#の用に文字列のメソッドになっていない。 ✕ "abc".Length ◯ len("abc") [[https://methane.hatenablog.jp/entry/20090702/1246556675|len が関数になっている理由]] ==== switch case文はない ==== Pythonにswitch文が実装されない理由として、公式ドキュメントには以下のように記述されています。 >if… elif… elif… else の繰り返しで簡単に同じことができます。switch 文の構文に関する提案がいくつかありましたが、範囲判定をするべきか、あるいはどのようにするべきかについての合意は (まだ) 得られていません。 [[https://docs.python.org/ja/3/faq/design.html?highlight=switch%23why-isn-t-there-a-switch-or-case-statement-in-python#why-isn-t-there-a-switch-or-case-statement-in-python|Python に switch や case 文がないのはなぜですか?]] If文を駆使することで同様の処理が行えるため、議論こそあったようですが実装はされなかったようです。\\ しかし、Python3.10からはswitch文と同様の構文の「match文」が導入されます。 [[https://camp.trainocate.co.jp/magazine/python-switch-case/|Pythonでswitch/case文がない理由は?代用方法を解説!]] ==== フォーマット書式 ==== line = "{0}さんの身長は{1}cmです。{0}さんの体重は{2}kgです。".format("山田", 190, 105.3) print(line) # 山田さんの身長は190cmです。山田さんの体重は105.3kgです。 単純に左から順に一対一になっている場合は、以下のようにインデックス番号を省略できます。 line = "{}さんの身長は{}cmです。{}さんの体重は{}kgです。".format("山田", 190, 105.3) print(line) # 山田さんの身長は190cmです。山田さんの体重は105.3kgです。 [[https://gammasoft.jp/blog/python-string-format/|Pythonの文字列フォーマット(formatメソッドの使い方)]] === 日付書式 === 代表的なものがこちらです。より詳しい情報は[[https://docs.python.org/ja/3/library/datetime.html#strftime-and-strptime-behavior|公式ドキュメント]]を確認してください。 * %Y: 年(4桁) * %y: 年(2桁) * %m: 月 * %d: 日 * %H: 時 * %M: 分 * %S: 秒 * %f: マイクロ秒 * %A: 曜日 * %a: 曜日(短縮形) * %w: 曜日(数値: 0-6, 0:日曜日, 1:月曜日, … 6:土曜日) import datetime dt = datetime.datetime.today() # ローカルな現在の日付と時刻を取得 print(dt) # 2021-10-29 15:58:08.356501 [[https://atmarkit.itmedia.co.jp/ait/articles/2111/09/news015.html|[解決!Python]日付や時刻をYYMMDDhhmmssなどの形式に書式化するには]] === ミリ秒 === %fはマイクロ秒なのでミリ秒にする。 from datetime import datetime date_s = (datetime.now().strftime('%Y-%m-%d %H:%M:%S.%f')[:-3]) print(date_s) # 2021-01-23 03:00:29.052 [[https://www.delftstack.com/ja/howto/python/python-datetime-milliseconds/|Python で DateTime をミリ秒単位の文字列に変換する]] ==== 例外処理 ==== * [[https://note.nkmk.me/python-try-except-else-finally/|Pythonの例外処理(try, except, else, finally)]] * [[https://qiita.com/qqhann/items/5dbe38be94bd44b20937|Pythonの例外処理で例外の内容を知る]] === 例外を発生させる === 自作の例外を発生させるraiseの使い方 * [[https://uxmilk.jp/39845|Pythonで例外を発生させる:raise]] * [[https://www.delftstack.com/ja/howto/python/manually-raise-exceptions-in-python/|Python で手動で例外を発生させる]] * [[https://techacademy.jp/magazine/22124|Pythonで自作の例外を発生させるraiseの使い方を現役エンジニアが解説【初心者向け】]] === catchした例外をそのまま親まで届ける === [[https://teratail.com/questions/292576|【python/例外処理】 catchした例外をそのまま親まで届ける方法はありますか?]] 式を伴わなければ、 raise は現在のスコープで最終的に有効になっている例外を再送出します。 try: ... except Exception as e: raise そもそもraiseには例外インスタンスが渡せるので try: ... except Exception as e: raise e # ★ でもいいです。こちらだとTracebackに★の行の情報が加えられます。 except節の中でifの分岐などでraiseが2箇所以上現れるならこちらで。 ==== 配列およびリスト処理 ==== * [[https://note.nkmk.me/python-split-strip-list-join/|Python, splitでカンマ区切り文字列を分割、空白を削除しリスト化]] * [[https://pyhoo.jp/python-list-change|Python list(リスト)の変更|追加・並替・更新など]] * [[https://note.nkmk.me/python-copy-deepcopy/|Pythonの浅いコピーと深いコピー: copy(), deepcopy()]] ==== クラス内のメソッドを別のメソッド内で呼ぶ ==== クラス内のメソッドを別のメソッド内で呼ぶと「name 'xxx' is not defined」エラーになる。\\ 関数の順序は関係ない、クラス内のメソッドの第1引数は必ずselfを付け、self.xxx で呼び出す必要があった。 Pythonではメソッドの第一引数は「self」が必須であり、自身のクラスのインスタンスを受け取るとコーディング規約で決まっているらしい。\\ >Pythonのメソッド引数に書く「self」はしばしば,他言語からのPython移民を中心に「ウザイ」「キモイ」「消えてなくなれ」と攻撃の対象となることが多いのです。 >https://coreblog.org/ats/translation-of-why-explicit-self-has-to-stay/ * [[https://teratail.com/questions/138900|pythonでのクラス内のメソッドを別のメソッド内で使う方法]] * [[https://python.ms/self/|なんで self を書かないといけないの?]] * [[https://qiita.com/DataBridge/items/2580522199e407abd8df|Python3のメソッド(第一引数にself必須)とスタティックメソッド(引数不要)の違いを検証してみた]] * [[https://qiita.com/yaboxi_/items/70249bd5a977d614aa4c|Pythonにおける「self.クラス変数」でのクラス変数・インスタンス変数の参照順]] ===== 自作クラスで'module' object is not callable エラー ===== 原因はimportの書き方が間違っているから\\ 以下の書き方だとエラーになる。 import myClass myInstance = myClass() 下の書き方に修正すると動く。 from (myClassのファイル名) import myClass myInstance = myClass() [[http://mynetabook.blogspot.com/2018/10/importtypeerror-module-object-is-not.html|[トラブル] 自作クラスのimport時にTypeError: 'module' object is not callableになる]] ===== コマンドライン引数の処理 ===== [[https://atmarkit.itmedia.co.jp/ait/articles/2112/21/news025.html|[解決!Python]Pythonスクリプトに与えられたコマンドライン引数を処理するには]] ===== ファイル関連 ===== ==== パス操作 ==== import os filepath = r"C:\temp\Image.bmp" # ファイル名 os.path.basename() print(os.path.basename(filepath)) # 'Image.bmp' # フォルダ名 os.path.dirname() print(os.path.dirname(filepath)) # 'C:\temp' # 拡張子の取得 os.path.splitext() print(os.path.splitext(filepath)[1]) # '.bmp' # 拡張子なしのパス os.path.splitext() print(os.path.splitext(filepath)[0]) # 'C:\temp\Image' # 拡張子なしのファイル名 os.path.basename(), os.path.splitext() print(os.path.splitext(os.path.basename(filepath))[0]) # 'Image' # ルートディレクトリ os.path.splitdrive() print(os.path.splitdrive(filepath)[0]) # 'C:' [[https://imagingsolution.net/program/python/python-basic/get_file_name_extension_etc/|【Python/os】パスからファイル名、拡張子、フォルダ名などを取得する]] ==== ファイル読み書き ==== [[https://atmarkit.itmedia.co.jp/ait/articles/2104/27/news021.html|[解決!Python]エンコーディングを指定して、シフトJISなどのファイルを読み書きするには]] ==== フォルダ未存在時作成 ==== フォルダ名は、フルパスで指定すればいい。 import os new_path = "demo_folder" if not os.path.exists(new_path): os.mkdir(new_path) [[https://qiita.com/yusa0827/items/b70780c7ee38a8282375|Python フォルダの作成 既存かチェックあり]] ===== HTTP クライアント ===== urllibライブラリーを使用する。 * [[https://qiita.com/hoto17296/items/8fcf55cc6cd823a18217|Python の HTTP クライアントは urllib.request で十分]] * [[https://atmarkit.itmedia.co.jp/ait/articles/1910/15/news018.html|[Python入門]urllib.requestモジュールによるWebページの取得]] * [[https://docs.python.org/ja/3/howto/urllib2.html|urllib パッケージを使ってインターネット上のリソースを取得するには]] * [[https://dev.classmethod.jp/articles/python-urllib-examples/|urllibだけである程度HTTPリクエストを頑張る]]