目次
Python
C#で作成したものをPythonに移植する上で調査したメモ
Visual Studio 2022を使用するも、途中で拡張機能が充実しているVisual Studio Codeに変更した。
Visual Studio関連
Visual Studio上でUTF-8にして保存したい
Visual StudioでPythonファイルを保存するとShift-JISになりデバッグエラーになってしまう。
UTF-8で保存できるようにしたい。
- EditorConfig ファイルをプロジェクトに追加する
- EditorConfig ファイルの下記内容を記載
- EditorConfig
root = true [*.py] charset = utf-8
Visual Studioのエディターで行番号を表示する
Pythonはエラーに行番号が出てくるので表示するようにしておく。
Visual Studio Code関連
環境構築
拡張機能
【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のコードを記述する際の基本的なコーディングスタイルを定めている。
main関数の書き方
Pythonはスクリプトなのでmain関数を定義する必要はありません。慣例的にmain関数を定義することがあります。
- main
import sys def main(argv): print('Hello, World!') return 0 if __name__ == '__main__': sys.exit(main(sys.argv))
fromやimportの基礎
コメント記載方法
Google Styleを採用
- Googleスタイル
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クラスを作成して、その中でメンバ変数として定義する。重複定義とか気にせず単純にした。
定義変数は、英大文字を使用する。
- const.py
class Const(): # クラス変数として定数を定義する FOO = 1 BAR = "TEST"
使用方法
- main.py
From Const import Const a = Const.Foo
文字列の囲み
Python では、単一引用符 ' で囲まれた文字列と、二重引用符 “ で囲まれた文字列は同じです。
PEP 8では、どちらを推奨するかの立場は示しません。
C#からの移植なので、二重引用符(ダブルクォーテーション)をベースとする。
文字列の長さ取得
switch case文はない
Pythonにswitch文が実装されない理由として、公式ドキュメントには以下のように記述されています。
if… elif… elif… else の繰り返しで簡単に同じことができます。switch 文の構文に関する提案がいくつかありましたが、範囲判定をするべきか、あるいはどのようにするべきかについての合意は (まだ) 得られていません。
Python に switch や case 文がないのはなぜですか?
If文を駆使することで同様の処理が行えるため、議論こそあったようですが実装はされなかったようです。
しかし、Python3.10からはswitch文と同様の構文の「match文」が導入されます。
フォーマット書式
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です。
日付書式
代表的なものがこちらです。より詳しい情報は公式ドキュメントを確認してください。
- %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
ミリ秒
%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
例外処理
例外を発生させる
自作の例外を発生させるraiseの使い方
catchした例外をそのまま親まで届ける
【python/例外処理】 catchした例外をそのまま親まで届ける方法はありますか?
式を伴わなければ、 raise は現在のスコープで最終的に有効になっている例外を再送出します。
try: ... except Exception as e: raise そもそもraiseには例外インスタンスが渡せるので
try: ... except Exception as e: raise e # ★ でもいいです。こちらだとTracebackに★の行の情報が加えられます。 except節の中でifの分岐などでraiseが2箇所以上現れるならこちらで。
配列およびリスト処理
クラス内のメソッドを別のメソッド内で呼ぶ
クラス内のメソッドを別のメソッド内で呼ぶと「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/
自作クラスで'module' object is not callable エラー
原因はimportの書き方が間違っているから
以下の書き方だとエラーになる。
import myClass myInstance = myClass()
下の書き方に修正すると動く。
from (myClassのファイル名) import myClass myInstance = myClass()
[トラブル] 自作クラスのimport時にTypeError: 'module' object is not callableになる
コマンドライン引数の処理
ファイル関連
パス操作
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:'
ファイル読み書き
フォルダ未存在時作成
フォルダ名は、フルパスで指定すればいい。
import os new_path = "demo_folder" if not os.path.exists(new_path): os.mkdir(new_path)