2

uwsgi.itの api 用の python クライアントに取り組んでおり、 http 要求を介して送信される多くの (オプションの) パラメータを受け入れるメソッドを記述する必要があることがわかりました。

最初は、ユーザーが挿入できるパラメーターを宣言したかったのですが、それらは非常に多いため、ユーザーがdict内に自由に何かを挿入できるようにするのではなく、パラメーターとしてリストを使用する方が簡単で安全だと思いました。このようなもので:

def alarms(self, container=None, _class=None, color=None,
           vassal=None, level=None, line=None, filename=None, 
           func=None, with_total=None, range=None):
    params = {k: v for k, v in locals().iteritems() if k != 'self' and v}
    if '_class' in params:
        params['class'] = params['_class']
        del params['_class']
    return self.get('alarms', params)

しかし、それはかなり醜く、「_class」パラメーターを処理するこの方法は本当に好きではありません。したがって、私の頭に浮かぶ他の可能性は、何でも (または **kwargs) を含むことができる辞書を受け入れ、受け入れられたキーを docstring にリストしてから、入力をサニタイズすることです。可能な方法は、許可されたパラメーターのみを受け入れる「プライベート」メソッドを宣言することです。しかし、その後、同じ問題が再び発生します。なにか提案を?非常に多くのパラメーターを持つメソッドのベストプラクティスはありますか?

4

3 に答える 3

2

**kwargsを使用することは良い考えであり、セットを使用してキーを簡単にサニタイズできることに同意します。私は Python 2.6 を使用しているため、集合内包表記はありませんが、私のコードはより最新のバージョンに簡単に変換できるはずです。

FWIW、私は実際にこのプログラムのバージョンを昨夜遅くに投稿しましたが、その後、不適切なパラメーターを修正する必要があると判断したため、一時的に削除しました。こちらが改訂版です。

validate_params.py

#! /usr/bin/env python

''' Validate the keys in kwargs

    Test keys against a container (set, tuple, list) of good keys,
    supplying a value of None for missing keys

    Also, if a key ends with an underscore, strip it.

    Written by PM 2Ring 2014.11.15

    From 
    http://stackoverflow.com/questions/26945235/best-practice-handle-functions-with-lots-of-parameters-and-reserved-names

'''

import sys

def test(**kwargs):
    good_keys = ("container", "class_", "color", 
        "vassal", "level", "line", "filename", 
        "func", "with_total", "range")
    new_kwargs = validate_keys(kwargs, good_keys)
    for t in new_kwargs.items():
        print "%-12s : %r" % t


#def alarms(**kwargs):
    #good_keys = ("container", "class_", "color", 
        #"vassal", "level", "line", "filename", 
        #"func", "with_total", "range")
    #return self.get('alarms', validate_keys(kwargs, good_keys))


def validate_keys(kwargs, good_keys):
    good_keys = set(good_keys)
    bad_keys = set(kwargs.keys()) - good_keys
    if bad_keys:
        bad_keys = ', '.join(bad_keys)
        print >>sys.stderr, "Unknown parameters: %s\n" % bad_keys
        raise KeyError, bad_keys

    new_kwargs = {}  
    for k in good_keys:
        new_kwargs[k.rstrip('_')] = kwargs.get(k, None)
    return new_kwargs


test(color="red", class_="top",
    #bar=1, foo=3,  #Some bad keys
    level=2, func="copy",filename="text.txt")

出力

container    : None
with_total   : None
level        : 2
color        : 'red'
filename     : 'text.txt'
vassal       : None
range        : None
func         : 'copy'
line         : None
class        : 'top'
于 2014-11-15T13:59:32.823 に答える
1

ロジックを整理するためにできることの 1 つは、dict の理解を次のように変更することです。

params = {k.strip("_"): v for k, v in locals().iteritems() if k != 'self' and v is not None}
#          ^^^^^^^^^^^

その後、クラスについて何もする必要はありません。また、後者は引数が「プライベート」であることを示しているため、おそらくclass_を優先して使用し_classますが、前者は「キーワードを識別子として使用する必要がある」というヒントであることがよくあります。

于 2014-11-15T14:43:40.847 に答える
1

メソッドが多くの入力を必要とし始めた場合、考慮すべきソフトウェア設計の 1 つの方法は、これらの入力値ごとにプロパティを含む特別なクラスを宣言し、インスタンス化して使用とは別にデータを設定することです。そうすれば、各プロパティへの参照ではなく、(カプセル化するクラスへの) メソッド シグネチャに 1 つの参照を渡すだけで済みます。オブジェクト モデルが大きくなるにつれて、新しいクラスを簡単に生成し、必要に応じてそのプロパティを検証するのに役立つビルダー メソッドと検証メソッドを追加することもできます。

Python でクラスを定義する方法

また、コードの形式、機能、保守性を改善する方法として、設計パターンと SOLID 設計原則を検討してください。これらのパターンに精通することで、真にゲームを向上させ、ソフトウェア プログラマーからリードまたはエンジニアに移行するために必要な知識を得ることができます。

http://en.wikipedia.org/wiki/SOLID_%28object-directional_design%29

http://en.wikipedia.org/wiki/Encapsulation_%28オブジェクト指向プログラミング%29

http://en.wikipedia.org/wiki/Software_design_pattern

于 2014-11-15T14:58:30.367 に答える