Python「if name == ‘main’」の意味と使い方|モジュール実行制御の基本
if name == ‘main‘ とは?基礎知識
if __name__ == '__main__' は、Pythonスクリプトが直接実行された場合にのみコードを実行するための条件文です。この構文により、スクリプトファイルがモジュールとしてインポートされた場合と、直接実行された場合で異なる動作を制御できます。
name 変数の仕組み
直接実行時
# test.py
print(f"__name__ の値: {__name__}")
実行結果
python test.py
# 出力: __name__ の値: __main__
インポート時
# main.py
import test
# 出力: __name__ の値: test
基本的な使用方法
最もシンプルな例
hello.py
def say_hello():
print("Hello, World!")
if __name__ == '__main__':
say_hello()
実行パターン
# 直接実行: say_hello()が実行される
python hello.py
# インポート: say_hello()は実行されない
python -c "import hello"
関数定義と実行の分離
calculator.py
def add(a, b):
return a + b
def subtract(a, b):
return a - b
def main():
print("Calculator Test")
print(f"5 + 3 = {add(5, 3)}")
print(f"10 - 4 = {subtract(10, 4)}")
if __name__ == '__main__':
main()
実践的な活用例
コマンドライン引数の処理
script.py
import sys
def process_arguments():
if len(sys.argv) < 2:
print("Usage: python script.py <filename>")
return
filename = sys.argv[1]
print(f"Processing file: {filename}")
if __name__ == '__main__':
process_arguments()
argparseを使った高度な例
advanced_script.py
import argparse
def create_parser():
parser = argparse.ArgumentParser(description='File processor')
parser.add_argument('filename', help='Input file name')
parser.add_argument('--output', '-o', help='Output file name')
parser.add_argument('--verbose', '-v', action='store_true')
return parser
def main():
parser = create_parser()
args = parser.parse_args()
if args.verbose:
print(f"Processing {args.filename}")
# ファイル処理のロジック
process_file(args.filename, args.output)
def process_file(input_file, output_file=None):
print(f"Processing {input_file}")
if output_file:
print(f"Output will be written to {output_file}")
if __name__ == '__main__':
main()
モジュールとしての利用
再利用可能なモジュール設計
math_utils.py
def factorial(n):
if n <= 1:
return 1
return n * factorial(n - 1)
def fibonacci(n):
if n <= 1:
return n
return fibonacci(n - 1) + fibonacci(n - 2)
def run_tests():
print("Math Utils Test")
print(f"factorial(5) = {factorial(5)}")
print(f"fibonacci(8) = {fibonacci(8)}")
if __name__ == '__main__':
run_tests()
main.py で math_utils を使用
from math_utils import factorial, fibonacci
def main():
print("Main Application")
result = factorial(6)
fib = fibonacci(10)
print(f"Results: {result}, {fib}")
if __name__ == '__main__':
main()
テスト関数の実装
data_processor.py
def clean_data(data):
return [item.strip().lower() for item in data if item.strip()]
def validate_email(email):
return '@' in email and '.' in email
def test_functions():
# テストデータ
test_data = [' John ', 'JANE', '', ' bob ']
cleaned = clean_data(test_data)
print(f"Cleaned data: {cleaned}")
# メール検証テスト
emails = ['[email protected]', 'invalid-email', '[email protected]']
for email in emails:
valid = validate_email(email)
print(f"{email}: {'Valid' if valid else 'Invalid'}")
if __name__ == '__main__':
test_functions()
設定とエラーハンドリング
設定ファイルの読み込み
config_loader.py
import json
import os
def load_config(config_file='config.json'):
if not os.path.exists(config_file):
return create_default_config()
with open(config_file, 'r') as f:
return json.load(f)
def create_default_config():
return {
'database_url': 'sqlite:///default.db',
'debug': True,
'port': 8000
}
def main():
config = load_config()
print("Configuration loaded:")
for key, value in config.items():
print(f" {key}: {value}")
if __name__ == '__main__':
main()
例外処理を含む実装
file_processor.py
import os
import sys
def process_file(filename):
try:
with open(filename, 'r') as f:
content = f.read()
return len(content.split())
except FileNotFoundError:
print(f"Error: File '{filename}' not found")
return None
except PermissionError:
print(f"Error: Permission denied for '{filename}'")
return None
def main():
if len(sys.argv) != 2:
print("Usage: python file_processor.py <filename>")
sys.exit(1)
filename = sys.argv[1]
word_count = process_file(filename)
if word_count is not None:
print(f"Word count: {word_count}")
else:
sys.exit(1)
if __name__ == '__main__':
main()
デバッグとロギング
ログ機能付きスクリプト
logger_example.py
import logging
import sys
def setup_logging(level=logging.INFO):
logging.basicConfig(
level=level,
format='%(asctime)s - %(levelname)s - %(message)s',
handlers=[
logging.FileHandler('app.log'),
logging.StreamHandler(sys.stdout)
]
)
def process_data(data):
logging.info(f"Processing {len(data)} items")
processed = []
for item in data:
try:
result = item * 2
processed.append(result)
logging.debug(f"Processed item: {item} -> {result}")
except Exception as e:
logging.error(f"Error processing {item}: {e}")
logging.info(f"Successfully processed {len(processed)} items")
return processed
def main():
setup_logging(logging.DEBUG)
test_data = [1, 2, 3, 'invalid', 5]
results = process_data(test_data)
print(f"Results: {results}")
if __name__ == '__main__':
main()
パフォーマンス測定
実行時間の測定
benchmark.py
import time
import functools
def measure_time(func):
@functools.wraps(func)
def wrapper(*args, **kwargs):
start = time.time()
result = func(*args, **kwargs)
end = time.time()
print(f"{func.__name__} executed in {end - start:.4f} seconds")
return result
return wrapper
@measure_time
def slow_function():
time.sleep(1)
return "Completed"
@measure_time
def fast_function():
return sum(range(1000000))
def run_benchmarks():
print("Running benchmarks...")
slow_function()
fast_function()
if __name__ == '__main__':
run_benchmarks()
Web開発での活用
簡単なHTTPサーバー
simple_server.py
from http.server import HTTPServer, SimpleHTTPRequestHandler
import os
def start_server(port=8000, directory='.'):
os.chdir(directory)
server = HTTPServer(('localhost', port), SimpleHTTPRequestHandler)
print(f"Server running at http://localhost:{port}/")
try:
server.serve_forever()
except KeyboardInterrupt:
print("\nServer stopped")
server.shutdown()
if __name__ == '__main__':
import sys
port = int(sys.argv[1]) if len(sys.argv) > 1 else 8000
start_server(port)
Flask アプリケーション
flask_app.py
from flask import Flask, jsonify
app = Flask(__name__)
@app.route('/')
def hello():
return jsonify({"message": "Hello, World!"})
@app.route('/health')
def health():
return jsonify({"status": "healthy"})
def create_app():
return app
if __name__ == '__main__':
app.run(debug=True, host='0.0.0.0', port=5000)
データ処理スクリプト
CSV ファイル処理
csv_processor.py
import csv
import sys
def process_csv(filename):
try:
with open(filename, 'r') as f:
reader = csv.DictReader(f)
data = list(reader)
print(f"Loaded {len(data)} records")
return data
except FileNotFoundError:
print(f"File {filename} not found")
return []
def analyze_data(data):
if not data:
return
print("Data Analysis:")
print(f"Columns: {list(data[0].keys())}")
print(f"Records: {len(data)}")
def main():
if len(sys.argv) != 2:
print("Usage: python csv_processor.py <filename.csv>")
return
filename = sys.argv[1]
data = process_csv(filename)
analyze_data(data)
if __name__ == '__main__':
main()
テストとの統合
unittest との組み合わせ
test_example.py
import unittest
def add(a, b):
return a + b
def multiply(a, b):
return a * b
class TestMathFunctions(unittest.TestCase):
def test_add(self):
self.assertEqual(add(2, 3), 5)
self.assertEqual(add(-1, 1), 0)
def test_multiply(self):
self.assertEqual(multiply(3, 4), 12)
self.assertEqual(multiply(0, 5), 0)
def run_manual_tests():
print("Manual testing:")
print(f"add(5, 7) = {add(5, 7)}")
print(f"multiply(3, 6) = {multiply(3, 6)}")
if __name__ == '__main__':
# テストスイートの実行か手動テストかを選択
import sys
if '--unittest' in sys.argv:
unittest.main(argv=[sys.argv[0]])
else:
run_manual_tests()
実用的なベストプラクティス
環境変数の活用
env_config.py
import os
def get_config():
return {
'database_url': os.getenv('DATABASE_URL', 'sqlite:///default.db'),
'debug': os.getenv('DEBUG', 'False').lower() == 'true',
'secret_key': os.getenv('SECRET_KEY', 'dev-secret-key')
}
def validate_config(config):
required_keys = ['database_url', 'secret_key']
missing = [key for key in required_keys if not config.get(key)]
if missing:
raise ValueError(f"Missing required config: {missing}")
def main():
config = get_config()
try:
validate_config(config)
print("Configuration is valid:")
for key, value in config.items():
# secret_keyは表示しない
display_value = '***' if 'secret' in key.lower() else value
print(f" {key}: {display_value}")
except ValueError as e:
print(f"Configuration error: {e}")
if __name__ == '__main__':
main()
マルチプロセッシング対応
parallel_processor.py
import multiprocessing
import time
def worker_function(item):
# 重い処理をシミュレート
time.sleep(0.1)
return item ** 2
def process_parallel(data, num_processes=None):
if num_processes is None:
num_processes = multiprocessing.cpu_count()
with multiprocessing.Pool(num_processes) as pool:
results = pool.map(worker_function, data)
return results
def process_sequential(data):
return [worker_function(item) for item in data]
def main():
data = list(range(100))
# 並列処理
start = time.time()
parallel_results = process_parallel(data)
parallel_time = time.time() - start
# 逐次処理
start = time.time()
sequential_results = process_sequential(data)
sequential_time = time.time() - start
print(f"Parallel processing: {parallel_time:.2f}s")
print(f"Sequential processing: {sequential_time:.2f}s")
print(f"Speedup: {sequential_time/parallel_time:.2f}x")
if __name__ == '__main__':
main()
まとめ
if __name__ == '__main__' は、Pythonプログラムの実行制御において重要な役割を果たします。この構文を適切に使用することで、再利用可能で保守性の高いコードを作成できます。
主要なポイント:
- 実行制御: スクリプト直接実行時のみコードを実行
- モジュール化: インポート時には実行されない
- テスト統合: テスト関数の実装に最適
- コマンドライン: 引数処理との組み合わせ
- デバッグ: 開発時の動作確認に便利
この構文をマスターすることで、Pythonプログラムの設計と実装がより柔軟で効率的になります。特に大規模なプロジェクトや再利用可能なモジュールの開発において、必須のテクニックといえるでしょう。
■プロンプトだけでオリジナルアプリを開発・公開してみた!!
■AI時代の第一歩!「AI駆動開発コース」はじめました!
テックジム東京本校で先行開始。
■テックジム東京本校
「武田塾」のプログラミング版といえば「テックジム」。
講義動画なし、教科書なし。「進捗管理とコーチング」で効率学習。
より早く、より安く、しかも対面型のプログラミングスクールです。
<短期講習>5日で5万円の「Pythonミニキャンプ」開催中。
<月1開催>放送作家による映像ディレクター養成講座
<オンライン無料>ゼロから始めるPython爆速講座

