Python-schemaの使用

16954 ワード

私たちがどんなアプリケーションをしても、ユーザーの入力と付き合う限り、ユーザーの入力データを信じないという原則があります.ユーザー入力に対して厳格な検証を行うことを意味し、web開発時には一般的に入力データはJSON形式でバックエンドAPIに送信され、APIは入力データに対して検証を行う.一般的に私は多くの判断を加えて、各種if、コードが醜いことを招いて、1種の方式が比較的に優雅にユーザーのデータを検証することができますか?Schemaが役に立ちました.
インストール
pip install schema

Schema
基本タイプ:条件を満たすと現在の値が返され、満たさないとエラーが報告されます.
from schema import Schema

print Schema(int).validate(10)      # 10
print Schema(int).validate('10')    # schema.SchemaUnexpectedTypeError

List/tuple/set:list/tuple/setのいずれかの条件を満たすと現在の値が返され、満たさないとエラーが報告されます!!
from schema import Schema

print Schema([int, float]).validate([1, 2, 3, 3.3])             # [1, 2, 3, 3.3]
print Schema([int, float]).validate([1, 2, 3, 4])               # [1, 2, 3, 4]
print Schema([int, float]).validate(['a', 'b', 'c', 'd'])       # schema.SchemaError

ディクショナリ:まず、モデルディクショナリとデータディクショナリのKeyが完全に同じかどうか、異なる場合はエラーを報告します.その後、データ辞書のvalueはモデル辞書に対応するvalueを検証し、検証が通過した場合にデータが返されます.そうしないと、エラーが発生します.
from schema import Schema

print Schema({"name": str, "age": int}).validate({"name": "laozhang", "age": 18})           # {'age': 18, 'name': 'laozhang'}
print Schema({"name": str, "age": int}).validate({"name": "laozhang"})                      # schema.SchemaMissingKeyError
print Schema({"name": str, "age": int}).validate({"name": 18, "age": 18})                   # schema.SchemaError
print Schema({"name": str, "age": int}).validate({"name": 18, "age": 18, "addr": "  "})   # schema.SchemaWrongKeyError
Schema入力された辞書をモデル辞書と呼ぶことが多いvalidate入力された辞書をデータ辞書と呼ぶことが多い
呼び出し可能なオブジェクト:呼び出し可能なオブジェクトの条件を満たすと、現在の値が返され、エラーが報告されます.
from schema import Schema

print Schema(lambda x: 1 < x < 8).validate(5)       # 5
print Schema(lambda x: 1 < x < 8).validate(8)       # schema.SchemaError

Use Use検証時に自動的に値を変換してくれる
from schema import Schema, Use

print Schema(Use(int)).validate(10)                 # 10-->int  
print Schema(Use(int)).validate('10')               # 10-->int  
print Schema(Use(int)).validate('xiaoming')         # schema.SchemaError

Const
私たちは知っていますUse検証の時、自動的に値を変換してあげます.Const元のデータをそのまま保持できる:
from schema import Schema, Use, Const

print Schema(Const(Use(int))).validate('10')        # 10-->str  

And And複数の条件が満たされているか検証する
from schema import Schema, And

print Schema(And(int, lambda x: x < x < 8)).validate(5)             # 5
print Schema(And(int, lambda x: x < x < 8)).validate(8)             # schema.SchemaError
print Schema(And(int, lambda x: x < x < 8)).validate('5')           # schema.SchemaError

Or Orいずれかの条件を満たしているか検証する
from schema import Schema, Or, Use

print Schema(Or(lambda x: 1 < x < 8, Use(int))).validate(5)                 # 5-->int  
print Schema(Or(lambda x: 1 < x < 8, Use(int))).validate(8)                 # 8-->int  
print Schema(Or(lambda x: 1 < x < 8, Use(int))).validate('8')               # 8-->int  
print Schema(Or(lambda x: 1 < x < 8, Use(int))).validate('xiaoming')        # schema.SchemaError

Optional Schema入力辞書の検証は使いやすいが、入力辞書がモデル辞書keyと一致しないため、エラーが発生することが多い.この場合、Optionalオプションの検証辞書を使用することができる.
from schema import Schema, Optional

print Schema({"name": str, Optional("age"): int}).validate({"name": "laozhang"})                                # {'name': 'laozhang'}
print Schema({"name": str, Optional("age"): int}).validate({"name": "laozhang", "age": 18})                     # {'age': 18, 'name': 'laozhang'}
print Schema({"name": str, Optional("age"): int}).validate({"name": 18, "age": 18})                             # schema.SchemaError
print Schema({"name": str, Optional("age"): int}).validate({"name": "laozhang", "age": 18, "addr": "  "})     # schema.SchemaWrongKeyError

また、Optionalでは、以下のようにデフォルト値を設定することもできます.
print Schema({"name": str, Optional("age", default=18): int}).validate({"name": "laozhang"})                    # {'age': 18, 'name': 'laozhang'}

上記の方法は、データ辞書のkeyがモデル辞書のkeyより少ない場合にのみ使用され、データ辞書のkeyがモデル辞書より多い場合、どのように無視検証を行うのでしょうか.ignore_extra_keysパラメータを使用して、次のようにTrueに設定できます.
from schema import Schema

print Schema({"name": str, "age": int}, ignore_extra_keys=True).validate({"name": "laozhang", "age": 18, "addr": "  "})       # {'age': 18, 'name': 'laozhang'}

Forbidden Forbiddenあるキーを禁止することができる:
from schema import Schema, Forbidden

print Schema({Forbidden('name'): str, 'age': int}).validate({"age": 15})                            # {"age": 15}
print Schema({Forbidden('name'): str, 'age': int}).validate({"name": "laozhang", "age": 15})        # schema.SchemaForbiddenKeyError
print Schema({Forbidden('name'): str, 'age': int}).validate({"name": 10, "age": 15})                # schema.SchemaWrongKeyError

秘密鍵の無効化ペアの値によって拒否されるかどうかが決定されることに注意してください.
from schema import Schema, Forbidden

print Schema({Forbidden('name'): int, 'name': str}).validate({'name': 'laozhang'})                  # {'name': 'laozhang'}
print Schema({Forbidden('name'): str, 'name': str}).validate({'name': 'laozhang'})                  # schema.SchemaForbiddenKeyError

また、Forbiddenの優先度はOptionalより高い:
from schema import Schema, Forbidden, Optional

print Schema({Forbidden('name'): str, Optional('name'): str}).validate({"name": "laozhang"})        # schema.SchemaForbiddenKeyError

Regex Regex正規表現による照合検証が可能
import re
from schema import Regex

print Regex('^foo').validate('football')        # football
print Regex('^foo').validate('basketball')      # schema.SchemaError

# flags=re.I     
print Regex('[A-Z]+', flags=re.I).validate('football')      # football

もちろん、Regex同じく配合可能Schema併用:
from schema import Schema, Regex

print Schema(Regex('^foo')).validate('football')            # football

カスタムエラーSchemaAndOrUse・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・
from schema import Schema

print Schema(int, error='       ').validate('abc')      # schema.SchemaUnexpectedTypeError: