Python のオブジェクト指向プログラミングを使用する場合、継続的な調整を行わずに親クラスへの変更や追加を処理できるようにサブクラスを設計する必要がある状況によく遭遇します。この状況は、クラスのinitメソッドで、特に継承を扱う場合によく発生します。
この状況を適切に処理するために、Python に*args
は と の**kwargs
両方の規則が用意されています。主要な例に入る前に、これらの規則が何であるかを簡単に理解しましょう。
*args
: 可変数の非キーワード引数を関数に渡すことができます。これらの引数はタプルに取り込まれます。
**kwargs
: 可変数のキーワード引数を関数に渡すことができます。これらのパラメータは辞書に取り込まれます。
この知識を踏まえて、これらの規則が適用されるシナリオを見てみましょう。
シナリオ: 親クラスの拡張
コンストラクターで 2 つのパラメーターを受け入れるクラス A があるとします。
class A:
def __init__(self, arg1, arg2):
self.arg1 = arg1
self.arg2 = arg2
print(f"类A的构造函数带有参数: {arg1}, {arg2}")
ここで、クラス A を継承するクラス B を設計し、クラス B を毎回変更せずにクラス A の変更に適応させたい場合は、 と を使用してクラス B の init メソッドをジェネリック*args
に**kwargs
できます。
class B(A):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs) # 将所有参数传递给类A的构造函数
print("类B的构造函数")
クラス B をこのように設計すると、クラス Bに渡されるパラメータがクラス A の更新要件を満たしている限り、クラス Aのinitメソッドのシグネチャを変更してもクラス B のインスタンス化が中断されることはありません。
例えば:
b = B("Hello", "World")
# 输出:
# 类A的构造函数带有参数: Hello, World
# 类B的构造函数
このアプローチの利点:
-
柔軟性: クラス B からクラス A への変更は復元力を維持します。これは、大規模なプロジェクトやライブラリで特に便利です。たとえば、クラス A は更新を受け取るモジュールの一部である可能性があります。
-
保守性: プロジェクトが成長するにつれて、開発者はクラス A が変更されるたびにクラス B に再度アクセスする必要がなくなります。
-
よりクリーンなコード: パラメーターをそれぞれ個別に処理するのではなく、一般的な方法ですべてのパラメーターをキャプチャし、コードをよりクリーンかつ明確にします。
予防:
このアプローチには柔軟性がありますが、注意も必要です。
すべてのパラメーターを盲目的に渡すと、特にクラス A のコンストラクターがクラス B のインスタンス化方法と互換性のない方法で変更された場合、意図しない結果が生じることがあります。
エラー メッセージが派生クラスではなくスーパークラスのコンストラクターを指している場合があるため、デバッグは少し難しい場合があります。
結論は:
*args と **kwargs を使用した柔軟なコンストラクターの設計は、特に継承を扱う場合に、Python 開発者のツールボックスにある強力なツールです。このアプローチを理解して採用することで、開発者は変更と反復を通じてクラスの柔軟性と保守性を維持できるようになります。いつものように、柔軟性は有益ですが、柔軟性が意図しない問題を引き起こさないように注意することも重要です。
英文
AIのおすすめ本
AIは日々変化していますが、高層ビルは良好な基礎から切り離すことはできません。人工知能の原理と実践について学ぶことに興味がありますか? これ以上探さない!AI の原則と実践に関する書籍は、AI の世界について詳しく知りたい人にとって最適なリソースです。この分野の第一線の専門家によって書かれたこの包括的なガイドは、機械学習の基礎からインテリジェント システムを構築するための高度なテクニックまですべてをカバーしています。初心者であろうと経験豊富な AI 実践者であろうと、この本はあなたをカバーします。では、なぜ待つのでしょうか?
人工知能の原理と実践は、人工知能とデータ サイエンスのさまざまな重要なシステムの古典を包括的にカバーしています。
北京大学出版局、人工知能の原理と実践 人工知能とデータサイエンスの入門から習得まで 機械学習と深層学習アルゴリズムの原理を説明