Python3 〜 オブジェクト指向のイミュータブル(不変)なクラス

スポンサーリンク

はじめに

バイオインフォマティクスでは、DNA配列やタンパク質構造のデータを扱うことが多く、データの整合性を保ちながら処理を進めることが求められます。そのため、Pythonのオブジェクト指向プログラミング(OOP)の考え方を理解し、適切に活用することが重要です。

本記事では、データクラス(dataclass)の frozen オプションを用いたイミュータブル(不変)なクラスの基本と応用について解説します。特に、バイオインフォマティクスで役立つ活用例を紹介しながら、その利点を考察していきます。


データクラス(dataclass)とは?

データクラス(dataclass)は、Python3.7 以降で導入されたデータ管理に特化したクラスです。通常のクラスに比べて、次のようなメリットがあります。

  1. ボイラープレートコードを削減__init____repr__ などの自動生成)
  2. 可読性が向上(データ構造を簡潔に定義可能)
  3. 型アノテーションと組み合わせて厳密なデータ管理が可能

基本的な dataclass の例を見てみましょう。

from dataclasses import dataclass

@dataclass
class DNASequence:
    id: str
    sequence: str

このコードだけで、DNASequence クラスには __init____repr__ などが自動生成され、オブジェクトの作成や表示が簡単になります。

seq = DNASequence(id="seq1", sequence="ATCGGTA")
print(seq)
# DNASequence(id='seq1', sequence='ATCGGTA')

frozen=True でイミュータブルなデータクラスを作成

デフォルトでは、データクラスのフィールドは変更可能(ミュータブル)です。しかし、一度作成したオブジェクトのデータを変更したくない場合frozen=True を指定することでイミュータブルなクラスを作成できます。

from dataclasses import dataclass

@dataclass(frozen=True)
class DNASequence:
    id: str
    sequence: str

この DNASequence クラスは、一度作成するとフィールドの値を変更できなくなります。

seq = DNASequence(id="seq1", sequence="ATCGGTA")
print(seq.sequence)  # 出力: ATCGGTA

# seq.sequence = "GCTAC"  # これはエラーになる(AttributeError: cannot assign to field 'sequence')

frozen を使う利点

  1. データの整合性を維持
    • 例えば、バイオインフォマティクスの解析中にDNA配列データが意図せず変更されるのを防ぐ。
  2. ハッシュ化可能(辞書のキーとして使用可能)
    • frozen=True にすると __hash__ メソッドが自動実装され、辞書のキーや set の要素として使える。
seq_dict = {DNASequence("seq1", "ATCGGTA"): "Sample 1"}
print(seq_dict)

応用:バイオインフォマティクスでの活用例

1. DNA配列のオブジェクト管理

バイオインフォマティクスでは、DNAやタンパク質の配列データを多数扱うため、イミュータブルなデータクラスを利用することで、データの一貫性を保ちながら処理を行うことができます。

from typing import List

@dataclass(frozen=True)
class DNASequence:
    id: str
    sequence: str

@dataclass(frozen=True)
class Sample:
    sample_id: str
    sequences: List[DNASequence]
seq1 = DNASequence(id="seq1", sequence="ATCGGTA")
seq2 = DNASequence(id="seq2", sequence="GCTAGCT")
sample = Sample(sample_id="sample_001", sequences=[seq1, seq2])

print(sample)
# Sample(sample_id='sample_001', sequences=[DNASequence(id='seq1', sequence='ATCGGTA'), DNASequence(id='seq2', sequence='GCTAGCT')])

2. 変異解析(Mutation Analysis)

DNA配列の変異検出を行う際、オリジナルの配列と変異後の配列を扱うことが多いため、元データを不変にすることで安全に解析できます。

@dataclass(frozen=True)
class Mutation:
    original: DNASequence
    mutated: DNASequence
    position: int
mut = Mutation(original=seq1, mutated=DNASequence("seq1_mut", "ATCGCTA"), position=6)
print(mut)
# Mutation(original=DNASequence(id='seq1', sequence='ATCGGTA'), mutated=DNASequence(id='seq1_mut', sequence='ATCGCTA'), position=6)

3. 配列解析結果のキャッシュ

頻繁に行うDNA配列の計算結果をキャッシュする際、イミュータブルなクラスをキーとして使うと、データの整合性を保ちつつ高速な検索が可能になります。

from functools import lru_cache

@lru_cache(maxsize=None)
def gc_content(seq: str) -> float:
    return (seq.count("G") + seq.count("C")) / len(seq)

print(gc_content("ATCGGTA"))  # 0.4285
print(gc_content("GCTAGCT"))  # 0.5714

まとめ

バイオインフォマティクスでは、データの整合性を維持しながら解析を行うことが重要です。そのため、Pythonの dataclass(frozen=True) を活用することで、イミュータブルなデータ構造を作成し、安全かつ効率的にデータを管理 できます!!

frozen の主な利点

データの改変防止(データの一貫性を保つ)
ハッシュ化可能(辞書や set での利用が可能)
バイオインフォマティクスの解析データに適用しやすい(DNA配列、変異データの管理など)

Pythonを活用して、より安全で効率的なバイオインフォマティクス解析を実現しましょう〜!

タイトルとURLをコピーしました