2017-05-13 5 views
1

Ich verwende Dekoratoren, um Parameter zu validieren, die zu meiner Funktion kommen (über ein Wörterbuchobjekt), wenn ich 2 Schlüssel oder mehr habe, funktioniert es gut. Aber wenn ich nur den Schlüssel habe, gibt es einen Fehler zurück (check_person). I 2 definierten Funktionen, mein Problem zu veranschaulichen:Python Decorator Validierung

def required(**mandatory): 
     """ 

     :param mandatory: 
     :return: 
     """ 

     def decorator(f): 
      @wraps(f) 
      def wrapper(**dicts): 
       for argname, d in dicts.items(): 
        for key in mandatory.get(argname, []): 
         if key not in d: 
          raise Exception('Key "%s" is missing from argument "%s"' % (key, argname)) 
       return f(**dicts) 
      return wrapper 
     return decorator 

@required(json_request=(_PROVIDER, _REPORT)) 
def check_campaign(json_request): 
    """ 

    :param json_request: 
    :return: 
    """ 

    return True 

@required(json_request=(_NAME)) 
def check_person(json_request=None): 
    """ 

    :param json_request: 
    :return: 
    """ 
    return True 

Ich brauche check_person zu ändern:

if _NAME in json_request: 
     return True 
    return False 

, damit es funktioniert.

Wenn ich versuche:

self.assertTrue(validator.check_person(json_request=json.loads("""{"name": "Elon Musk"}"""))) 

oder speziell:

{"name": "Elon Musk"} 

ich:

Error 
Traceback (most recent call last): 
    File "/Users/spicyramen/Documents/OpenSource/Development/Python/gonzo/utils/validate/validator_test.py", line 46, in test_person 
    self.assertTrue(validator.check_person(json_request=json.loads("""{"name": "Elon Musk"}"""))) 
    File "/Users/spicyramen/Documents/OpenSource/Development/Python/gonzo/utils/validate/validator.py", line 26, in wrapper 
    raise Exception('Key "%s" is missing from argument "%s"' % (key, argname)) 
Exception: Key "n" is missing from argument "json_request" 

Wenn mein Wörterbuch mehr als 1 Schlüssel hat es funktioniert (wie check_campaign) .

Antwort

1

Das Problem ist eine subtile Syntaxunterscheidung.

Mit @required(json_request=(_PROVIDER, _REPORT)) ist Ihre Anfrage ein Tupel: (_PROVIDER, _REPORT).

Im Gegensatz dazu ist die Anforderung in Ihrem fehlgeschlagenen Beispiel @required(json_request=(_NAME)) nur der Wert _NAME. Um es zu einem Tupel zu machen, fügen Sie ein Komma hinzu: @required(json_request=(_NAME,)). Das sollte alle deine Probleme beheben.


Wie, warum du das genaue Fehler, Sie über das Argument laufen. Wenn es ein Tupel ist, funktioniert es wie Sie wollen. Wenn es eine Zeichenfolge ist, erhalten Sie jeden Buchstaben, wenn Sie darüber iterieren. Deshalb fehlt 'n': es ist der erste Buchstabe von 'name'.