「労働者が自分の仕事をうまくやりたいなら、まず自分の道具を研ぎ澄まさなければなりません。」 - 孔子、「論語。陸霊公」
表紙 > プログラミング > Python: 興味深いコード パターン

Python: 興味深いコード パターン

2024 年 11 月 8 日に公開
ブラウズ:614

Python: Interesting Code Patterns

私は主に Python を使って作業しており、ほぼ毎日コードをレビューしています。私たちのコードベースでは、フォーマットとリンティングは black と mypy を使用する CI ジョブによって処理されます。したがって、変更のみに焦点を当てます。

チームで作業するとき、特定のチーム メンバーにどのようなコードが期待されるかはすでにわかっています。新しい人がチームに加わるとコードレビューが面白くなります。興味深いと言ったのは、誰もが無意識に使用しているコーディング スタイルを持っているからです。良くも悪くも!私もいくつか持っているように、

  1. Optionaltypeの値を設定します。 通常、これらの変数は署名の一部です
# I used (long back) to do

def func(a: int, b: Optional[list] = None, c: Optional[Dict] = None):

    if b is None:
       b = []
    if c is None:
       c = {}

# Instead I do

def func(a: int, b: Optional[list] = None, c: Optional[Dict] = None):

    b = b or []
    c = c or {}
  1. dict を使用した単純な if..elif..else (最大 3 ~ 4) ステートメントの処理

これは、文字列を返すか、値に基づいて関数を呼び出す単純な使用例です

注: 3.10 からは、これの代わりに match を使用する必要があります。

する代わりに、

def get_number_of_wheels(vehicle: str):
    if vehicle == "car":
        wheels = 2
    elif vehicle == "bus":
        wheels = 6
    elif vehicle == "bicycle":
        wheels = 2
    else:
        raise ...

# I prefer doing, 

def get_number_of_wheels(vehicle: str):
    return {
       "car": 2,
       "bus": 6,
       "bicycle": 2
    }[vehicle]       # Raise is now KeyError

上記はいくつかの例ですが、私のコードをレビューする人にはさらに多くの例があるでしょう。

最近、新しい開発者が私のチームに加わり、気に入っているパターンに気づきましたが、それを単純な if..else ケースに変更するように依頼しました。まずパターンを示してから、変更を求める理由を説明します。

このコードはパラメータに対して何らかの処理を行うデコレータです。関数/メソッドが呼び出された引数と kwargs の数を出力する単純な (役に立たない) デコレータを作成しましょう。

def counter(is_cls_method: bool = False):
    """ print number of args & kwargs for func/method """
    def outer(f):
        def inner(*args, **kwargs):
            args_cnt = len(args)
            kwargs_cnt = len(kwargs)
            print(f"{f.__name__} called with {args_cnt=} & {kwargs_cnt=}")
            return f(*args, **kwargs)
        return inner
    return outer

@counter()
def test1(a, b, c):
    pass

class A:
    @counter(is_cls_method=True)
    def test1(self, a, b, c):
        pass


print("function")
test1(1, 2, c=3)
test1(a=1, b=2, c=3)

print("method")
a = A()
a.test1(1, 2, 3)
a.test1(1, b=2, c=3)

このコードを実行すると、次のように表示されます

function
test1 called with args_cnt=2 & kwargs_cnt=1
test1 called with args_cnt=0 & kwargs_cnt=3

method
test1 called with args_cnt=4 & kwargs_cnt=0
test1 called with args_cnt=2 & kwargs_cnt=2

正常に動作しますが、メソッドの場合は自分自身もカウントします。それを修正しましょう!

def counter(is_cls_method: bool = False):
    def outer(f):
        def inner(*args, **kwargs):
            args_cnt = len(args)

            if is_cls_method:   # Check added
               args_cnt -= 1    # Reduced count by 1

            kwargs_cnt = len(kwargs)
            print(f"{f.__name__} called with {args_cnt=} & {kwargs_cnt=}")
            return f(*args, **kwargs)
        return inner
    return outer

これは単純な if 句ですが、新しい開発者はブール値の興味深い使用法である別のことを行いました。

変更されたコードのみを表示しています...

   args_cnt = len(args[is_cls_method:])

Python の bool は単なる int であるため、解決策は if を使用するよりもはるかに優れています。元のコードは少し長く、この小さな変更は明らかではありませんが、基本的な Python ユーザーが使用するコード ベースでもあります。そして、行が何をしているのかを推測する必要がある場合は、それが明らかになるように変更する必要があると思います。

これについてどう思いますか。インデックスとしてブール値を使用しますか?
このような Python パターンは他にもありますか?

リリースステートメント この記事は次の場所に転載されています: https://dev.to/ninadmhatre/python-interesting-code-patterns-dh3?1 侵害がある場合は、[email protected] に連絡して削除してください。
最新のチュートリアル もっと>

免責事項: 提供されるすべてのリソースの一部はインターネットからのものです。お客様の著作権またはその他の権利および利益の侵害がある場合は、詳細な理由を説明し、著作権または権利および利益の証拠を提出して、電子メール [email protected] に送信してください。 できるだけ早く対応させていただきます。

Copyright© 2022 湘ICP备2022001581号-3