【ヒント】Python引数解析器 ― 悪い習慣
By khoanc, at: 2024年10月18日11:28
Estimated Reading Time: __READING_TIME__ minutes
![[TIPS] Python Argument Parser - Bad Practices](/media/filer_public_thumbnails/filer_public/53/22/532205b4-0a89-4637-9f86-e7d316454d2b/python_argument_parsers_issues.png__1500x900_crop_subsampling-2_upscale.png)
![[TIPS] Python Argument Parser - Bad Practices](/media/filer_public_thumbnails/filer_public/53/22/532205b4-0a89-4637-9f86-e7d316454d2b/python_argument_parsers_issues.png__400x240_crop_subsampling-2_upscale.png)
Pythonスクリプトで引数を渡す際の悪い習慣
1. sys.argv
の直接使用
import sys
def main():
if len(sys.argv) < 3:
print("Not enough arguments!")
return
arg1 = sys.argv[1]
arg2 = sys.argv[2]
if arg1 == 'option1':
print(f"Option 1 selected with value {arg2}")
elif arg1 == 'option2':
print(f"Option 2 selected with value {arg2}")
else:
print("Unknown option!")
if __name__ == "__main__":
main()
悪い習慣:引数の解析にsys.argv
を直接使用すると、エラーが発生しやすく、保守が困難になります。
修正:引数の解析にはargparse
モジュールを使用してください。より堅牢でユーザーフレンドリーな方法でコマンドライン引数を処理できます。
import argparse
def main():
parser = argparse.ArgumentParser(description="A sample argument parser.")
parser.add_argument('arg1', type=str, help="First argument")
parser.add_argument('arg2', type=str, help="Second argument")
args = parser.parse_args()
if args.arg1 == 'option1':
print(f"Option 1 selected with value {args.arg2}")
elif args.arg1 == 'option2':
print(f"Option 2 selected with value {args.arg2}")
else:
print("Unknown option!")
if __name__ == "__main__":
main()
2. 使用方法またはヘルプメッセージがない
import sys
def main():
if len(sys.argv) < 3:
print("Not enough arguments!")
return
arg1 = sys.argv[1]
arg2 = sys.argv[2]
if arg1 == 'option1':
print(f"Option 1 selected with value {arg2}")
elif arg1 == 'option2':
print(f"Option 2 selected with value {arg2}")
else:
print("Unknown option!")
if __name__ == "__main__":
main()
悪い習慣:使用方法またはヘルプメッセージがないと、ユーザーがスクリプトの使い方を理解するのが困難になります。
修正:argparse
モジュールを使用すると、ヘルプメッセージと使用方法が自動的に提供されます。
import argparse
def main():
parser = argparse.ArgumentParser(description="A sample argument parser.")
parser.add_argument('arg1', type=str, help="First argument")
parser.add_argument('arg2', type=str, help="Second argument")
args = parser.parse_args()
if args.arg1 == 'option1':
print(f"Option 1 selected with value {args.arg2}")
elif args.arg1 == 'option2':
print(f"Option 2 selected with value {args.arg2}")
else:
print("Unknown option!")
if __name__ == "__main__":
main()
引数の検証がない
import sys
def main():
if len(sys.argv) < 3:
print("Not enough arguments!")
return
arg1 = sys.argv[1]
arg2 = sys.argv[2]
if arg1 == 'option1':
print(f"Option 1 selected with value {arg2}")
elif arg1 == 'option2':
print(f"Option 2 selected with value {arg2}")
else:
print("Unknown option!")
if __name__ == "__main__":
main()
悪い習慣:引数を検証しないと、ランタイムエラーや予期せぬ動作が発生する可能性があります。
修正:argparse
を使用して、引数の型を指定し、それに応じて検証します。
import argparse
def main():
parser = argparse.ArgumentParser(description="A sample argument parser.")
parser.add_argument('arg1', type=str, choices=['option1', 'option2'], help="First argument")
parser.add_argument('arg2', type=str, help="Second argument")
args = parser.parse_args()
if args.arg1 == 'option1':
print(f"Option 1 selected with value {args.arg2}")
elif args.arg1 == 'option2':
print(f"Option 2 selected with value {args.arg2}")
if __name__ == "__main__":
main()
例外ケースの無視
import sys
def main():
if len(sys.argv) < 3:
print("Not enough arguments!")
return
arg1 = sys.argv[1]
arg2 = sys.argv[2]
if arg1 == 'option1':
print(f"Option 1 selected with value {arg2}")
elif arg1 == 'option2':
print(f"Option 2 selected with value {arg2}")
else:
print("Unknown option!")
if __name__ == "__main__":
main()
悪い習慣:引数の不足、データ型の誤り、無効な値などの例外ケースを処理していません。
修正:argparse
のデフォルト値、型チェック、必須引数などの機能を使用して、例外ケースを処理します。
import argparse
def main():
parser = argparse.ArgumentParser(description="A sample argument parser.")
parser.add_argument('arg1', type=str, choices=['option1', 'option2'], help="First argument")
parser.add_argument('arg2', type=str, help="Second argument")
parser.add_argument('--optional', type=int, default=0, help="An optional argument")
args = parser.parse_args()
if args.arg1 == 'option1':
print(f"Option 1 selected with value {args.arg2} and optional {args.optional}")
elif args.arg1 == 'option2':
print(f"Option 2 selected with value {args.arg2} and optional {args.optional}")
if __name__ == "__main__":
main()
引数の命名が不適切
import sys
def main():
if len(sys.argv) < 3:
print("Not enough arguments!")
return
arg1 = sys.argv[1]
arg2 = sys.argv[2]
if arg1 == 'option1':
print(f"Option 1 selected with value {arg2}")
elif arg1 == 'option2':
print(f"Option 2 selected with value {arg2}")
else:
print("Unknown option!")
if __name__ == "__main__":
main()
悪い習慣:説明が不足している、または曖昧な引数名を使用すると、ユーザーを混乱させる可能性があります。
修正:目的を明確に伝える、明確で分かりやすい引数名を使用してください。
import argparse
def main():
parser = argparse.ArgumentParser(description="A sample argument parser.")
parser.add_argument('command', type=str, choices=['start', 'stop'], help="Command to execute")
parser.add_argument('value', type=str, help="Value associated with the command")
args = parser.parse_args()
if args.command == 'start':
print(f"Starting with value {args.value}")
elif args.command == 'stop':
print(f"Stopping with value {args.value}")
if __name__ == "__main__":
main()