Python でのオプションの連鎖

Migel Hewage Nimesha 2023年6月21日
  1. try-except を使用して Python でオプションのチェーンを実装する
  2. getattr を使用して Python でオプションのチェーンを実装する
  3. get(key, value) を使用して Python でオプションのチェーンを実装する
  4. メソッドの組み合わせを使用して Python でオプションのチェーンを実装する
  5. getattr をドロップインとして使用して、Python でオプションのチェーンを実装する
  6. glom を使用して Python でオプションのチェーンを実装する
  7. 辞書とオブジェクトで読み取り可能なメソッドを使用して、Python でオプションのチェーンを実装する
  8. まとめ
Python でのオプションの連鎖

Python は、主にシステム スクリプト、サーバー側の Web 開発、およびソフトウェア開発で使用されるプログラミング言語です。 また、コードの可読性を向上させる単純な構文で構成されています。

Python の機能の中でも、オプショナル チェーンは、ネストされたオブジェクト プロパティにアクセスするための安全で簡潔な方法です。 これは、その時点で null の可能性がある、または null でない可能性があるプロパティを呼び出してクエリを実行するプロセスです。

オプションのチェーンを使用することで、手動でチェックするのではなく、オブジェクト内のプロパティが使用可能かどうかを内部的にチェックできます。

オプションのチェーンは、オペレーターに残されたプロパティが定義済みか未定義かをチェックします。 プロパティが null でない場合、呼び出しは成功し、無効または未定義の場合は undefined を返します。

ここでは、エラーを報告する代わりに、未定義の値を返します。 また、メソッドが存在しない場合でも、これは関数呼び出しで正常に機能します。

この概念は、Claude Pache、Gabriel Isenberg、Daniel Rosenwasser、Dustin Savery が執筆した ECMA International の Technical Committee 39 – ECMAScript によって最近導入されました。

よりクリーンなコードを書く場合、オプションの連鎖は便利な機能です。

以下は、Python でオプションのチェーンを実装する際に使用できるいくつかの方法です。 関数を構築するときに、これらのコード チャンクを使用できます。

try-except を使用して Python でオプションのチェーンを実装する

オプションの連鎖の最もpythonicな方法は以下のとおりです。

try:
    # statements

except (NameError, AttributeError) as e:
    # statements (else)

この方法では、try コマンドと except コマンドを使用します。 try 内には、フローを制御するために使用されるステートメントが含まれていますが、except は、命令をプログラムに渡す際に発生したエラーを処理するために使用されるステートメントで構成されています。

プログラムが実行されると、例外が発生する可能性があります。 次に、エラーとそれがどのように発生したかを示すメッセージを出力して、プログラムを中断します。

中断を防ぐには、それらをキャッチする必要があります。 したがって、このような例外処理は、エラー防止コードの取得に役立ちます。

ここでは、NameErrorAttributeError という 2つの主なエラーを考えています。 未定義の変数や関数を使用すると、NameError が発生することがあります。

ユーザーが無効な属性参照を試みた場合、参照は失敗し、AttributeError が発生する可能性があります。 また、スペルのバリエーションは AttributeError として発生します。

上記で説明したように、オプションの連鎖のこの Pythonic アプローチは、プロパティが定義されているかどうかにかかわらず、例外を処理しながらプロパティを呼び出すのに役立ちます。

getattr を使用して Python でオプションのチェーンを実装する

上記の方法の代わりに、getattr を使用することもオプションの連鎖の別の方法です。

getattr(getattr(foo, "bar", None), "baz", None)

ここでは、指定されたオブジェクトから指定された属性の値を返す getattr 関数を使用します。 オブジェクト名は文字列である必要があり、名前付き属性の場合は、その属性の値を返します。

ただし、指定された属性が存在しない場合は、デフォルト値が返されるか、または AttributeError がスローされます。

この getattr 関数内では、getattr(foo, 'bar', None) がオブジェクトであり、baz が属性であり、None がデフォルト値です。

get(key, value) を使用して Python でオプションのチェーンを実装する

辞書の場合、get(key, value) を使用できます。

{"foo": {"bar": "baz"}}.get("foo", {}).get("bar")

ディクショナリは、キー: 値 ペアとして格納された、順序付けられた、変更可能な、重複しないデータ値のコレクションです。 ここで、'foo''bar'、および 'baz' は、Python で使用するプレースホルダーです。

{'foo': {'bar': 'baz'}} はディクショナリで、これを使って keyvalue を持つ 2つの get 関数を使用しています。 ここで、get 関数は、指定されたキーでアイテムの値を返します。

最初の get 関数は 'foo' としてのキーと {} の値で構成され、2 番目の 'bar' としてのキーのみで構成されます。

上記のコード スニペットのように、辞書を使用する場合でも、オプションの連鎖の概念を適応させることができます。

メソッドの組み合わせを使用して Python でオプションのチェーンを実装する

以下は、オプションの連鎖で従うことができる別の方法です。 方法の組み合わせです。

from functools import reduce


def optional_chain(obj, keys):
    try:
        reduce(getattr, keys.split("."), root)
    except AttributeError:
        return None


optional_chain(foo, "bar.baz")

最初に、中間結果を保存し、最終的な合計のみを返す functools から reduce モジュールをインポートする必要があります。 次に、関数 optional_chain が 2つのパラメーターで定義されます。

その後、最初に説明したメソッドを try および except コントロールで適応させることができます。 try および except コマンド内で、getattr 関数を使用しました。

getattr の機能については、2 番目のメソッドで説明しました。 最後に、2つのパラメーターを定義して optional_chain を呼び出します。

getattr をドロップインとして使用して、Python でオプションのチェーンを実装する

上記のように getattr を拡張せずにドロップインとして使用できます。

from functools import reduce


def rgetattr(obj, attr, *args):
    def _getattr(obj, attr):
        return getattr(obj, attr, *args)

    return reduce(_getattr, attr.split("."), obj)

モジュールをインポートした後、3つのパラメーターを持つ rgetattr という名前の関数を定義しました。 次に、関数 getattr をドロップインとして定義します。

パスが存在しない場合、rgetattrAttributeError をスローし、None の代わりにデフォルトを指定できます。

glom を使用して Python でオプションのチェーンを実装する

オプションのチェーンで使用できる別の方法は、glom を使用することです。

from glom import glom

target = {"a": {"b": {"c": "d"}}}
glom(target, "a.b.c", default=None)

最初のステップとして、モジュール glom をライブラリからインポートする必要があります。 次に、ターゲットは、a, b, および c を使用して辞書の形式で定義されています。 また、dc の対応する値です。

その後、関数 glomtargeta.b.c をその内部に指定して呼び出されました。 例外が発生した場合、デフォルト値として None が出力されます。

辞書とオブジェクトで読み取り可能なメソッドを使用して、Python でオプションのチェーンを実装する

以下の方法に適応させることで、辞書やオブジェクトで使用するときにコードをより読みやすくすることができます。

def optional_chain(root, *keys):
    result = root
    for k in keys:
        if isinstance(result, dict):
            result = result.get(k, None)
        else:
            result = getattr(result, k, None)
        if result is None:
            break
    return result

最初に、optional_chain という名前の関数を定義し、for ループと if-else ステートメントを実行しました。 else 部分で結果を取得するために、フロー内で getattr 関数を使用しました。

この関数を使用する場合、最初の引数の後に keys を追加する必要があります。

obj = {"a": {"b": {"c": {"d": 1}}}}
print(optional_chain(obj, "a", "b"), optional_chain(obj, "a", "z"))

まとめ

全体として、上記の方法は、Python でオプションのチェーンが必要な場合に適応できる方法です。

解決するプロセスとパフォーマンスの問題がわかっている場合は、tryexcept のアプローチを使用して時期尚早の最適化を回避できます。 また、getattr を使用してコードを反映させることもできます。

Migel Hewage Nimesha avatar Migel Hewage Nimesha avatar

Nimesha is a Full-stack Software Engineer for more than five years, he loves technology, as technology has the power to solve our many problems within just a minute. He have been contributing to various projects over the last 5+ years and working with almost all the so-called 03 tiers(DB, M-Tier, and Client). Recently, he has started working with DevOps technologies such as Azure administration, Kubernetes, Terraform automation, and Bash scripting as well.