Learn in 10 minutes

Learn in 10 minutes

10分で学ぶPython

Pythonは、簡潔な構文と強力な機能で知られる高級なインタプリテッドプログラミング言語です。このチュートリアルは、最新のPython 3.13+ バージョンに基づいており、Pythonを迅速に学ぶのに役立ちます。

1. 最初のPythonプログラムの作成

簡単なプログラムから始めましょう。hello.pyという名前のファイルを作成し、以下のコードを入力します:

print("Hello, World!")

ファイルを保存し、端末またはコマンドラインで以下のコマンドを実行します:

python hello.py

出力は以下のようになります:

Hello, World!

この簡単なプログラムは、Pythonの基本的な出力機能を紹介します。print()関数は、コンソールにテキスト情報を表示するために使用されます。

2. 基本構文

Pythonの構文はシンプルで理解しやすいです。Pythonは、他の言語が使用する中括弧{}とは異なり、インデントを使用してコードブロックを定義します。

# これはコメントです
print("Hello, World!")

Pythonの基本構文ルール:

  • インデント:デフォルトでは、コードブロックのレベルを示すために4つのスペースが使用されます。例えば、関数やループ内のコードはインデントが必要です。
  • コメント:1行のコメントは#で始まり、複数行のコメントは三重引用符"""または'''を使用します。
  • ステートメント:通常、1行に1つのステートメントがあり、行末にセミコロン;は必要ありません。
  • コードブロック:インデントで定義され、iffor、または関数の本体などで使用されます。

複数行コメントの例:

"""
これは複数行のコメントです、
複数行にわたります。
"""

インデントは、Pythonの構文の重要な特徴であり、コードブロックの階層構造を定義します:

if True:
    print("この行はインデントされています")
    print("この行もインデントされています")
print("この行はインデントされていません")

3. 変数とデータ型

Pythonでは、変数はデータを格納するためのコンテナです。Pythonは動的型付け言語であり、変数の型を事前に宣言する必要はありません。

基本的な変数命名ルール

  • 変数名には、文字、数字、アンダースコアのみを含めることができます。
  • 変数名は数字で始めることはできません。
  • 変数名は大文字と小文字を区別します。
  • Pythonのキーワードを変数名として使用することはできません。

変数の型は割り当てられた値によって決定されます。Pythonの主な基本データ型は以下の通りです

  • 整数 (int):例:42 または -10、サイズに制限はありません。
  • 浮動小数点数 (float):例:3.14 または 2.5e3(科学的記数法)。
  • 文字列 (str):例:"hello" または 'world'、シングルクォートまたはダブルクォートを使用。
  • ブール値 (bool)True または False
  • NoneType (None)Noneで表され、nullまたは値がないことを示します。

Pythonは、コードの可読性を向上させるために型ヒントをサポートしており、静的チェックやIDEのサポートに使用されますが、実行時の動作には影響しません:

name: str = "Alice"
age: int = 25

3.1 数値型 (Number)

Pythonは、整数 (int)、浮動小数点数 (float)、複素数 (complex) の3つの数値型をサポートしています。

# 整数
age = 25
population = 1000000

# 浮動小数点数
temperature = 36.5
pi = 3.14159

# 複素数
complex_num = 3 + 4j

3.2 文字列 (String)

文字列は、シングルクォートまたはダブルクォートで囲まれた文字のシーケンスです。

single_quote = 'シングルクォートの文字列'
double_quote = "ダブルクォートの文字列"
multiline = """これは
複数行の文字列です"""

文字列操作:

text = "Python programming"
print(len(text))        # 文字列の長さ
print(text.upper())     # 大文字に変換
print(text.lower())     # 小文字に変換
print(text[0])          # 最初の文字にアクセス
print(text[2:6])        # 文字列のスライシング

3.3 ブール型 (Boolean)

ブール型には、TrueFalseの2つの値があります。

is_active = True
is_complete = False

# ブール演算
result1 = True and False  # False
result2 = True or False   # True
result3 = not True        # False

3.4 None型 (None)

Noneは、nullまたは値がない状態を表します。

value = None

if value is None:
    print("値はnullです")

4. データ構造

Pythonには、データを格納および操作するためのいくつかの組み込みデータ構造があります。以下は、よく使用されるデータ構造とその使用方法です。

4.1 リスト (List)

リストは、順序付けられ変更可能なコレクションです。リストに要素を追加、削除、または変更できます。リストは角括弧[]で定義されます。

numbers = [1, 2, 3, 4, 5]
numbers.append(6)      # 要素の追加
numbers.insert(0, 0)   # 特定の位置に挿入
numbers.remove(3)      # 特定の値を削除
numbers[0] = 10        # 要素の変更
print(numbers)         # [10, 2, 4, 5, 6]

リストのスライシングでサブリストにアクセス:

numbers = [10, 20, 30, 40, 50]
print(numbers[1:4])    # 出力: [20, 30, 40]
print(numbers[:3])     # 出力: [10, 20, 30]
print(numbers[-2:])    # 出力: [40, 50]

リスト内包表記:

squares = [x**2 for x in range(5)]
print(squares)         # [0, 1, 4, 9, 16]

even_squares = [x**2 for x in range(10) if x % 2 == 0]
print(even_squares)    # [0, 4, 16, 36, 64]

4.2 タプル (Tuple)

タプルは、順序付けられているが変更不可能なコレクションです。一度作成されたタプルの要素は変更できません。タプルは丸括弧()で定義されます。変更不可のため、リストよりも一般に高速で、辞書のキーとして使用できます。

point = (10, 20)
x, y = point  # アンパッキング
print(x, y)   # 出力: 10 20

単一要素のタプルにはカンマが必要です:

single_tuple = (42,)

4.3 辞書 (Dict)

辞書は、キー-値のペアのコレクションで、Python 3.7+では順序付けされています。各キーは一意で、値に関連付けられています。辞書は中括弧{}で定義されます。

student = {
    "name": "John",
    "age": 20,
    "major": "Computer Science"
}

# 辞書のアクセスと変更
print(student["name"])
student["age"] = 21
student["gpa"] = 3.8

# 安全なアクセス
print(student.get("phone", "提供されていません"))

# 辞書のイテレーション
for key, value in student.items():
    print(f"{key}: {value}")

辞書内包表記:

# 平方の辞書を作成
squares_dict = {x: x**2 for x in range(5)}
print(squares_dict)  # {0: 0, 1: 1, 2: 4, 3: 9, 4: 16}

# 条件付き辞書内包表記
even_squares_dict = {x: x**2 for x in range(10) if x % 2 == 0}
print(even_squares_dict)  # {0: 0, 2: 4, 4: 16, 6: 36, 8: 64}

4.4 セット (Set)

セットは、重複のない要素の順序付けられていないコレクションです。中括弧{}またはset()で定義されます。

# セットの作成
fruits = {"apple", "banana", "orange"}
numbers = set([1, 2, 3, 3, 4, 4, 5])  # 自動的に重複を削除
print(numbers)  # {1, 2, 3, 4, 5}

# セット操作
set1 = {1, 2, 3, 4}
set2 = {3, 4, 5, 6}

print(set1 | set2)  # 和集合: {1, 2, 3, 4, 5, 6}
print(set1 & set2)  # 積集合: {3, 4}
print(set1 - set2)  # 差集合: {1, 2}
print(set1 ^ set2)  # 対称差: {1, 2, 5, 6}

5. 演算と演算子

Pythonは、算術、比較、論理、ビット、アイデンティティ演算子など、さまざまな計算や比較のための豊富な演算子を提供します。

  • 算術演算子+-*///(整数除算)、%(剰余)、**(べき乗)。
  • 比較演算子==!=><>=<=
  • 論理演算子andornot
  • メンバーシップ演算子innot in
  • アイデンティティ演算子isis not

5.1 算術演算子

算術演算子は数学的演算に使用されます。演算子の優先順位は数学的ルールに従い(例:**+-よりも優先されます)、括弧()で優先順位を変更できます。

a, b = 10, 3

print(f"加算: {a + b}")      # 13
print(f"減算: {a - b}")      # 7
print(f"乗算: {a * b}")      # 30
print(f"除算: {a / b}")      # 3.333...
print(f"整数除算: {a // b}")  # 3
print(f"剰余: {a % b}")      # 1
print(f"べき乗: {a ** b}")    # 1000

5.2 比較演算子

比較演算子は2つの値を比較し、ブール値(TrueまたはFalse)を返します。

x, y = 5, 10

print(f"等しい: {x == y}")     # False
print(f"等しくない: {x != y}") # True
print(f"より大きい: {x > y}")  # False
print(f"より小さい: {x < y}")  # True
print(f"以上: {x >= y}")       # False
print(f"以下: {x <= y}")       # True

5.3 論理演算子

論理演算子はブール値(TrueまたはFalse)を結合または操作し、条件文でよく使用されます。

a, b = True, False

print(f"AND演算: {a and b}")  # False
print(f"OR演算: {a or b}")    # True
print(f"NOT演算: {not a}")    # False

5.4 アイデンティティ演算子

is演算子は、2つのオブジェクトのアイデンティティを比較し、同じメモリアドレスを参照しているかどうかを確認します(値の等価性だけでなく)。==とは異なり、内容を比較します。

list1 = [1, 2, 3]
list2 = [1, 2, 3]
list3 = list1

print(f"list1 is list2: {list1 is list2}")    # False
print(f"list1 is list3: {list1 is list3}")    # True
print(f"list1 == list2: {list1 == list2}")    # True

5.5 メンバーシップ演算子

メンバーシップ演算子は、値がシーケンス(リスト、タプル、文字列、セットなど)に含まれるかどうかをテストし、ブール値を返します。

fruits = ["apple", "banana", "orange"]

print(f"'apple' in fruits: {'apple' in fruits}")        # True
print(f"'grape' not in fruits: {'grape' not in fruits}")  # True

6. 制御フロー

Pythonは、プログラムの実行順序を管理するためのいくつかの制御フロー文を提供します。

6.1 if文

if文は条件を評価し、条件がTrueの場合にブロックを実行します。複雑な条件にはelifelseを使用します。

age = 20
if age >= 18:
    print("成人")
elif age >= 13:
    print("ティーン")
else:
    print("子供")

6.2 forループ

forループは、イテラブルオブジェクト(リスト、タプル、文字列、rangeなど)をイテレートします。

# リストのイテレーション
fruits = ["apple", "banana", "cherry"]
for fruit in fruits:
    print(fruit)

# range()を使用したループ
for i in range(5):
    print(i)  # 出力: 0, 1, 2, 3, 4

6.3 whileループ

whileループは、条件がTrueである限りブロックを実行し続けます。

count = 0
while count < 5:
    print(count)
    count += 1
  • breakとcontinuebreakはループを終了し、continueは現在のイテレーションをスキップします。
for i in range(10):
    if i == 5:
        break
    if i % 2 == 0:
        continue
    print(i)  # 出力: 1, 3

6.4 match文

Python 3.10で導入されたmatch文は、強力な構造的パターンマッチングを提供し、if/elif/elseチェーンの高度な代替として機能します。

http_status = 200

match http_status:
    case 200 | 201:
        print("成功")
    case 404:
        print("見つかりません")
    case 500:
        print("サーバーエラー")
    case _:  # ワイルドカード、他のすべての場合に一致
        print("不明なステータス")

7. 入出力

7.1 基本的な入出力

input()関数を使用してユーザー入力を取得し、print()関数を使用して情報を出力します。

# ユーザー入力の取得
name = input("名前を入力してください: ")
age = int(input("年齢を入力してください: "))

# 情報の出力
print("ようこそ", name)
print("あなたは", age, "歳です")

7.2 フォーマットされた出力 (f-strings)

Python 3.6+で導入されたf-strings(フォーマット文字列リテラル)は、文字列をフォーマットする便利で強力な方法です。文字列の前にfまたはFを付け、変数や式を中括弧{}で埋め込みます。

user = "Alice"
items = 3
total_cost = 45.5

# f-stringを使用したフォーマットメッセージ
message = f"ユーザー {user}{items} 個のアイテムを ${total_cost:.2f} で購入しました。"
print(message)

# f-strings内の式
print(f"2 + 3 は {2 + 3} です")

f-strings内の式と関数呼び出し:

width = 10
height = 5

# f-strings内の式
area = f"長方形の面積: {width * height}"
print(area)

# 関数の呼び出し
text = "python"
formatted = f"大文字: {text.upper()}, 長さ: {len(text)}"
print(formatted)

f-stringsのフォーマットオプション:

pi = 3.14159265359
large_number = 1234567

# 数値フォーマット
print(f"Pi (2桁): {pi:.2f}")
print(f"Pi (4桁): {pi:.4f}")
print(f"大きな数 (千区切り): {large_number:,}")
print(f"パーセンテージ: {0.85:.1%}")

# 文字列の配置
name = "Python"
print(f"左揃え: '{name:<10}'")
print(f"右揃え: '{name:>10}'")
print(f"中央揃え: '{name:^10}'")

日付と時刻のf-stringsを使用したフォーマット:

from datetime import datetime

now = datetime.now()
print(f"現在の時刻: {now}")
print(f"フォーマットされた時刻: {now:%Y-%m-%d %H:%M:%S}")
print(f"日付のみ: {now:%Y-%m-%d}")

9. 関数

Pythonの関数は、特定のタスクのための再利用可能なコードブロックで、defキーワードを使用して定義され、デフォルトパラメータ、可変引数、キーワード引数をサポートします。

基本的な関数の定義

def greet(name):
    """挨拶関数"""
    return f"こんにちは、{name}!"

# 関数の呼び出し
message = greet("John")
print(message)

キーワード引数

キーワード引数は、parameter_name=value構文を使用して渡されます。

def greet(name, greeting="こんにちは"):
    return f"{greeting}{name}!"

print(greet("Alice"))          # 出力: こんにちは、Alice!
print(greet("Bob", "やあ"))   # 出力: やあ、Bob!

可変引数

可変引数を使用すると、関数は任意の数の引数を受け入れることができます。位置引数(*args)またはキーワード引数(**kwargs)があります。

# 位置可変引数 (*args)
def sum_numbers(*args):
    return sum(args)

print(sum_numbers(1, 2, 3, 4))  # 出力: 10

# キーワード可変引数 (**kwargs)
def print_kwargs(**kwargs):
    for key, value in kwargs.items():
        print(f"{key}: {value}")

print_kwargs(name="Alice", age=25, city="東京")

関数アノテーション

関数アノテーションは、関数のパラメータと戻り値に記述的なメタデータを追加し、可読性とドキュメントを向上させます。

def calculate_area(length: float, width: float) -> float:
    """長方形の面積を計算"""
    return length * width

def process_user(name: str, age: int, active: bool = True) -> dict:
    """ユーザー情報の処理"""
    return {
        "name": name,
        "age": age,
        "active": active
    }

10. ラムダ式

ラムダ式は、匿名の関数を作成し、小さな関数を簡潔に定義する方法を提供します。

square = lambda x: x ** 2
print(square(5))  # 出力: 25

mapfilterなどの高階関数とよく使用されます:

numbers = [1, 2, 3, 4]
squares = list(map(lambda x: x ** 2, numbers))
print(squares)  # 出力: [1, 4, 9, 16]

11. クラスとオブジェクト

Pythonは、classキーワードを使用してオブジェクト指向プログラミングをサポートします:

class Person:
    """人クラス"""
    
    def __init__(self, name, age):
        """コンストラクタ"""
        self.name = name
        self.age = age
    
    def introduce(self):
        """紹介メソッド"""
        return f"私は{self.name}{self.age}歳です"
    
    def have_birthday(self):
        """誕生日メソッド"""
        self.age += 1
        return f"{self.name}は誕生日を迎え、今{self.age}歳です"

# オブジェクトの作成
person1 = Person("John", 25)
person2 = Person("Jane", 30)

print(person1.introduce())
print(person2.have_birthday())

11.1 クラス属性とインスタンス属性

Pythonでは、クラス属性とインスタンス属性は、クラスやオブジェクトにデータを格納するための2種類の属性です。

  • クラス属性:メソッド外で定義され、クラス自体に属し、すべてのインスタンス間で共有されます。
  • インスタンス属性:メソッド内(通常は__init__)で定義され、selfを介して特定のインスタンスにバインドされます。
class Student:
    # クラス属性
    school = "スタンフォード大学"
    student_count = 0
    
    def __init__(self, name, major):
        # インスタンス属性
        self.name = name
        self.major = major
        Student.student_count += 1
    
    @classmethod
    def get_student_count(cls):
        """クラスメソッド"""
        return cls.student_count
    
    @staticmethod
    def is_valid_age(age):
        """静的メソッド"""
        return 0 < age < 150

# 使用例
student1 = Student("John", "コンピュータサイエンス")
student2 = Student("Jane", "数学")

print(f"学校: {Student.school}")
print(f"総学生数: {Student.get_student_count()}")
print(f"有効な年齢: {Student.is_valid_age(20)}")

11.2 クラスの継承

継承により、クラス(サブクラス)は別のクラス(親クラス)の属性とメソッドを継承し、コードの再利用と拡張を可能にします。

class Animal:
    def __init__(self, name, species):
        self.name = name
        self.species = species
    
    def make_sound(self):
        return f"{self.name}が音を出す"
    
    def info(self):
        return f"{self.name}{self.species}です"

class Dog(Animal):
    def __init__(self, name, breed):
        super().__init__(name, "犬")
        self.breed = breed
    
    def make_sound(self):
        return f"{self.name}が吠える"
    
    def fetch(self):
        return f"{self.name}がボールを取ってくる"

class Cat(Animal):
    def __init__(self, name, color):
        super().__init__(name, "猫")
        self.color = color
    
    def make_sound(self):
        return f"{self.name}がニャーと鳴く"
    
    def climb(self):
        return f"{self.name}が木に登る"

# 継承の使用
dog = Dog("Buddy", "ゴールデンレトリバー")
cat = Cat("Mimi", "オレンジ")

print(dog.info())
print(dog.make_sound())
print(dog.fetch())

print(cat.info())
print(cat.make_sound())
print(cat.climb())

11.3 特殊メソッド(マジックメソッド)

特殊メソッド(またはマジックメソッド)は、特定のシナリオでPythonによって自動的に呼び出される二重アンダースコアのメソッドで、特定の動作を定義します。

class Rectangle:
    def __init__(self, width, height):
        self.width = width
        self.height = height
    
    def __str__(self):
        """文字列表現"""
        return f"Rectangle({self.width}x{self.height})"
    
    def __repr__(self):
        """公式の文字列表現"""
        return f"Rectangle(width={self.width}, height={self.height})"
    
    def __eq__(self, other):
        """等価比較"""
        if isinstance(other, Rectangle):
            return self.width == other.width and self.height == other.height
        return False
    
    def __lt__(self, other):
        """小なり比較(面積による)"""
        if isinstance(other, Rectangle):
            return self.area() < other.area()
        return NotImplemented
    
    def __add__(self, other):
        """加算操作"""
        if isinstance(other, Rectangle):
            return Rectangle(self.width + other.width, self.height + other.height)
        return NotImplemented
    
    def area(self):
        """面積の計算"""
        return self.width * self.height

# 特殊メソッドの使用
rect1 = Rectangle(3, 4)
rect2 = Rectangle(5, 6)
rect3 = Rectangle(3, 4)

print(rect1)           # Rectangle(3x4)
print(repr(rect1))     # Rectangle(width=3, height=4)
print(rect1 == rect3)  # True
print(rect1 < rect2)   # True
print(rect1 + rect2)   # Rectangle(8x10)

12. コンテキストマネージャ

コンテキストマネージャは、リソースの取得と解放を適切に行うためのもので、ファイルやデータベース接続などのリソース管理にwith文と一緒に使用されます。

12.1 コンテキストマネージャの使用

ファイル操作はコンテキストマネージャの一般的な使用例です:

with open("example.txt", "r") as file:
    content = file.read()
    print(content)

with文は、操作後にファイルが自動的に閉じられることを保証します。

12.2 カスタムコンテキストマネージャ

__enter__および__exit__メソッドを定義してカスタムコンテキストマネージャを作成します:

class DatabaseConnection:
    def __init__(self, database_name):
        self.database_name = database_name
        self.connection = None
    
    def __enter__(self):
        """コンテキストに入るときに呼び出される"""
        print(f"データベースに接続中: {self.database_name}")
        self.connection = f"{self.database_name}への接続"
        return self.connection
    
    def __exit__(self, exc_type, exc_value, traceback):
        """コンテキストを終了するときに呼び出される"""
        print(f"データベース接続を閉じる: {self.database_name}")
        if exc_type:
            print(f"例外が発生しました: {exc_type.__name__}: {exc_value}")
        self.connection = None
        return False  # 例外を抑制しない

# カスタムコンテキストマネージャの使用
with DatabaseConnection("user_database") as conn:
    print(f"接続を使用中: {conn}")
    print("データベース操作を実行中...")

contextlibモジュールを使用してコンテキストマネージャを作成:

from contextlib import contextmanager
import time

@contextmanager
def timer(operation_name):
    """タイマーコンテキストマネージャ"""
    print(f"{operation_name}を開始")
    start_time = time.time()
    try:
        yield
    finally:
        end_time = time.time()
        print(f"{operation_name}{end_time - start_time:.2f}秒で完了しました")

# デコレータベースのコンテキストマネージャの使用
with timer("データ処理"):
    # 時間のかかる操作をシミュレート
    time.sleep(1)
    print("データ処理中...")

13. 例外処理

例外処理は、プログラムの堅牢性を確保し、tryexceptelse、およびfinallyを使用して例外を管理します。

try:
    result = 10 / 0
except ZeroDivisionError:
    print("ゼロで割ることはできません!")
else:
    print("除算成功")
finally:
    print("これは常に実行されます")

出力:

ゼロで割ることはできません!
これは常に実行されます

14. ファイル操作

Pythonは、コンテキストマネージャを使用してファイルを読み書きするための簡単なメソッドを提供します。

14.1 ファイルの読み込み

テキストファイルの内容を読み込む:

with open("example.txt", "r") as file:
    content = file.read()
    print(content)

行ごとに読み込む:

with open("example.txt", "r") as file:
    for line in file:
        print(line.strip())

14.2 ファイルの書き込み

テキストファイルに書き込む:

with open("output.txt", "w") as file:
    file.write("こんにちは、Python!\n")

内容の追加:

with open("output.txt", "a") as file:
    file.write("新しい内容を追加。\n")

15. モジュールとパッケージ

モジュールはPythonコードを含むファイルで、パッケージは複数のモジュールを含むディレクトリです。importを使用してモジュールをインポートします:

import math
print(math.sqrt(16))  # 出力: 4.0

カスタムモジュールの例(ファイル名をmymodule.pyと仮定):

# mymodule.py
def say_hello():
    return "モジュールからこんにちは!"

インポートして使用:

import mymodule
print(mymodule.say_hello())  # 出力: モジュールからこんにちは!

16. スコープと名前空間

16.1 スコープ

スコープは、変数がアクセス可能な領域を定義します。Pythonは、変数の検索にLEGBルールに従います:

  • L (ローカル):関数またはクラスメソッド内。
  • E (エンクロージング):ネストされた関数の外側の関数(クロージャ)。
  • G (グローバル):モジュールレベル。
  • B (ビルトイン)print()len()などのビルトイン関数や例外。
x = "グローバル x"

def outer_func():
    x = "エンクロージング x"
    def inner_func():
        x = "ローカル x"
        print(x) # ローカルスコープ x にアクセス
    inner_func()
    print(x) # エンクロージングスコープ x にアクセス

outer_func()
print(x) # グローバルスコープ x にアクセス

globalまたはnonlocalを使用してスコープ変数を変更:

x = "グローバル"
def modify_global():
    global x
    x = "変更済み"
modify_global()
print(x)  # 出力: 変更済み

16.2 名前空間

名前空間は、名前からオブジェクトへのマッピングで、辞書のようなものです。

モジュール、関数、クラスはそれぞれ独自の名前空間を持ち、名前の衝突を防ぎます。globals()locals()を使用して名前空間を検査できます。

a_variable = 10

def some_function():
    b_variable = 20
    # locals() は現在のローカル名前空間辞書を返します
    print(f"ローカル: {locals()}")

print(f"グローバル: {globals().keys()}") # グローバル名前空間のキーを出力
some_function()

17. ジェネレータ

ジェネレータは、値を一度にすべて生成するのではなく、必要に応じて生成する特殊なイテレータで、大規模なデータセットに対してメモリ効率的です。

ジェネレータはyieldキーワードを使用して値を遅延的に返します:

def fibonacci(n):
    a, b = 0, 1
    for _ in range(n):
        yield a
        a, b = b, a + b

for num in fibonacci(5):
    print(num)  # 出力: 0, 1, 1, 2, 3

18. マルチスレッド

マルチスレッドは、プログラムが複数の操作を同時に実行できるようにし、ネットワークリクエストやファイル操作などのI/Oバウンドタスクに有用です。

Pythonのthreadingモジュールは、スレッドの作成と管理のためのツールを提供します。グローバルインタプリタロック(GIL)により、単一プロセス内での真のCPU並列処理は実現されませんが、I/Oバウンドタスクのパフォーマンスを大幅に向上させます。

import threading
import time

def worker(thread_name):
    print(f"スレッド {thread_name} 開始...")
    time.sleep(2) # 時間のかかる操作をシミュレート
    print(f"スレッド {thread_name} 終了。")

# スレッドの作成
thread1 = threading.Thread(target=worker, args=("A",))
thread2 = threading.Thread(target=worker, args=("B",))

# スレッドの開始
thread1.start()
thread2.start()

# すべてのスレッドの完了を待つ
thread1.join()
thread2.join()

print("すべてのスレッドが完了しました。")

19. 非同期プログラミング

非同期プログラミングは、高I/O、高並行性シナリオに最適で、スレッドの代わりにイベントループを使用してタスクを管理します。

Pythonは、asyncioライブラリとasync/await構文を介して非同期プログラミングをサポートします。

  • async def:コルーチンを定義します。
  • await:待機可能なオブジェクトが完了するまでコルーチンの実行を一時停止します。
import asyncio

async def say_hello():
    print("こんにちは")
    await asyncio.sleep(1) # 非ブロッキングのスリープ、I/Oをシミュレート
    print("世界")

async def main():
    # タスクを作成して待機
    await asyncio.create_task(say_hello())

# メインコルーチンの実行
asyncio.run(main())

出力:

こんにちは
世界