2012-03-02 14 views
0

を呼び出し中のように、私は関数に文字列をマップすると言うのマップを持っている追加の引数を追加します。私はタイプに基づいて、対応する検証関数を呼び出す必要がはそれで引数を持つ関数ポインタを送信し、その後

validator = {'first_name' : validate_str, 
      'last_name' : validate_str, 
      'phone' : validate_phone } 

値の私はマップの入力として私に与えられる

for name in elements: 
    # Validate the value of this name in the input map using the function 
    # input is the map that has the value for each of these fields 
    # elements is a list of all fields used to loop through one input at a time 
    if validator[name](input[name]) is False: 
     # Throw validation error 
    else: 
     # Do something else 

このシナリオのために、私はそれを行うことができるかどうかわからないない限り、これは正常に動作します:

与えられた文字列が必要な最大長さである場合validate_strもチェックします。

def validate_str(str, max-len): 
    # Throw error if len(str) > max-len 

MAX-lenは文字列に基づいて異なる場合がありますので、私は256文字で64の文字と最後の名前が言うとfirst_nameのためvalidate_str呼び出す必要があります。

このフィールドにはこのmax_lenがありますが、フィールドに基づいてmax-len引数がプリセットされたvalidate_str関数へのポインタを持つことが可能ですか?

何かのように:

validator = {'first_name' : validate_str(max-len=64), 
      'last_name' : validate_str(max-len=256), 
      'phone' : validate_phone } 
その後、

のような検証のためにそれを呼び出す:

if validator[name](str=input[name]) is False: 
    # The appropriate value for max-len goes with the function call and just the 
    # str is appended to the argument list while invoking. 

これは、我々は、その後のフィールドが最大-lenが一緒に送られていますどのような再び覚えておく必要はありませんように楽になりますそれと。

+0

可能性のあるタイプミス: 'validate'によって' validator'を意味しますか? '要素 'とは何ですか?これは、 'first_name'、' last_name'、または辞書のような文字列のリストのようです。 – ninjagecko

+0

間違いを修正しました。指摘してくれてありがとう。 –

+0

問題ありません。 'element 'を辞書' data = {' first_name ':' Bob '、' last_name ':' Bobley '、' phone ':1234567890} 'にして' field、data.items()の値として ' :バリデータでない場合[field](value):... '。はるかにきれいに読み取ります。 – ninjagecko

答えて

3

あなたは一つの引数(検証される文字列)の関数を作成するためにラムダを使用しますが、中内で定義された長さを持つことができます:

{'first-name':lambda x: validate-str(x, 64), ... 
+0

チャンピオンのように働きます。あなたへの誇り:-) –

+2

これは、OPが探していた2つの回答のうちの1つです。参考までに、これは関数をカリングするためにラムダを使っています。 – ninjagecko

0

これには2つの方法があります。

あなたが具体的に求めているのは、それをカレーする方法です(Scott Hunterは答えました)。

他の方法のような閉鎖のカスタムパラメータ、キャプチャ機能返す関数工場(「高次機能」)を使用することである。しかし、一般に

def makeStringValidator(maxLength=64): 
    def validator(string): 
     return len(string)<maxLength 
    return validator 

をこのシステムに自分自身を限定することで、フィールド間で「クロスカッティング」の検証ができなくなります。たとえば、別のフィールドとしてフィールドbirthday_day, birthday_month, birthday_yearがある場合は、毎日30日か31日かということを個別に確認できますが、どちらの月(2月のうるう年)を決定するかはその月を知らないでしょう。

しかし私は個人的にこのシステムを随時使用しています。このようなニーズが発生した場合は、後でもっと複雑なもので現在のシステムを補うことができます。

+0

ありがとう!これはうまくいく.. :-) –

関連する問題