0

次のコードに出くわしました。正常に動作していますが、クロージャーでさえないので奇妙に思えます。パフォーマンスやベストプラクティスの観点からコーディングするのが正しい方法なのか、それともすべてそうすべきなのか疑問に思っています内部にすべてのロジックがある通常の for ループに置き換えられましたか?

mylist = [
   {'one': 20,
    'two': 4},
   {'one': -6,
    'two': 64},
   {'one': 18,
    'two': 1},
   {'one': 16,
    'two': 100},
    # ...
]

def business_function(a_list):

    def compute_function(row):
        """
        suppose some more complex computations + appending extra values
        than this dummy example
        """
        row['total'] = row['one'] + row['two']
        return row

    def filter_function(item):
        """
        suppose some complex logic here
        """
        return item['one'] > 5

    # suppose there is some code here ...

    filtered_list = [compute_function(item) for item in a_list if filter_function(item)]

    # and some more code here ...

    return filtered_list


print business_function(mylist)
4

5 に答える 5

3

このようなローカル スコープの関数を使用しても問題はないと思います。

外部関数が頻繁に呼び出されない限り、パフォーマンスへの影響は最小限に抑えられます。たとえば、両方の関数のコードは、外側の関数が呼び出されたときに既にコンパイルされています。追加で行われるのは、コード オブジェクト定数が読み込まれ、関数にアタッチされ、その関数がローカル変数に格納されることだけです。

それらをローカルにスコープしておくことで、それらの有用性がbusiness_functionスコープのみにあることが十分に明確になります。

于 2012-08-19T20:00:18.430 に答える
2

ネストされた定義のこの使用は好きではありません。作成者は、読みやすさを向上させるため、または他の人が自分のプライベート関数を使用できないようにするために、これを行った可能性があります。

作成者がこれらの関数をプライベートとして「マーク」したい場合は、名前の前にアンダースコアを付ける必要があります。このようにして、これらの関数をコピーせずに、コードの他の部分で再利用することもできました。

彼が読みやすさを改善するためにこれを行った場合...まあ、それらをその機能の外に置いてみませんか? 彼らが実際の計算とフィルタリングを行った場合、独自のドキュメントとコメントを備えた「トップレベル」の関数になるに値します。

おそらくクロージャは、デコレータ、またはその他の非常にまれなケースでのみ使用する必要があります

于 2012-08-19T21:14:29.170 に答える
2

このメソッドが望むことを行うためのより良い方法があるという理由だけで、私はノーと言うつもりです.

  • 名前空間の衝突を防ぐには、関数を別のモジュールに入れます。
  • 単一の関数に関連付ける場合は、それらすべてを別のモジュールに入れます。
  • 実行を遅くする場合は、代わりにスリープ関数を使用してください。

それ以外の場合は、それらを通常の機能にします。

于 2012-08-19T20:02:19.760 に答える
2

これには小さな欠点があります。つまり、囲んでいる関数が呼び出されるたびに内部関数オブジェクトが作成されるため、パフォーマンスがわずかに低下します。ただし、これが問題になることはめったになく、コードのカプセル化が改善されているため、価値がある場合があります。

別の方法としてクラスを作成することもできますが、それではオーバーヘッドが削減されません。

于 2012-08-19T20:02:42.767 に答える
0

関数が外部関数のローカル変数を使用せず、簡単なワンライナーでない場合は、それらをグローバル スコープに配置します。

そうしないと、コードのリーダーは、外部関数が何をするかを理解するために、すべての関数定義を読むことを余儀なくされます (それらがクロージャーであり、外部ローカル変数を使用/変更する場合)。

それらが外部で定義されている場合、名前と、おそらく対応する docstring で、外部関数での役割を理解するのに十分な場合があります。

于 2012-08-19T21:10:51.563 に答える