ディレクトリ
Pythonのスキーマ命令
プロジェクト住所:GitHubの
1.スキーマそれは何ですか?
決して信頼ユーザーの入力データ - どんなに私たちが適用されないものを、限り、ユーザーの入力として扱うと、原則としてありません。私たちは、ユーザー入力の厳格な検証、一般的な入力データをJSON形式のWeb開発バックエンドAPIに送信され、入力データの検証を行うためのAPIなければならないことを意味します。私は通常、判決の多くを追加コードで結果は非常に醜いです、あれば、すべての種類、ユーザーデータにそれを検証するよりエレガントな方法はありませんか?スキーマに便利です。
スキーマは、それがコアクラスで、コードの数百行だ、非常に簡単です:スキーマ。
2.インストール
pip install schema
スキーマ型(int型、STR、フロートなど)1.求心性
例えば:
from schema import Schema
Schema(int).validate(10)
# 10
Schema(int).validate('10')
# SchemaUnexpectedTypeError: '10' should be instance of 'int'
スキーマ検証は、オブジェクト・タイプで渡さ方法を検証するために理解される指定されていない場合、着信データは、そうでなければ(SchemaUnexpectedTypeErrorがSchemaErrorのサブクラスである)のSchemaErrorを投げ、戻されます。
着信オブジェクトクラス2.スキーマ(__call__等の関数)を呼び出すことができ
例えば:
Schema(lambda x: 0<x<10).validate(5)
# 5
Schema(lambda x: 0<x<10).validate(57)
# SchemaError: <lambda>(57) should evaluate to True
カスタム機能:
def secre_validate(password):
password_list = ["123456", "666666", "888888", "abcdef", "aaaaaa", "112233"]
if password in password_list:
return False
return True
Schema(secre_validate, error="字符串已经存在").validate("123456")
# schema.SchemaError: 字符串已经存在
パラメータとして渡された内部スキーマ検証方法は、そうでない場合、例外がスローされ、入力データが返された場合、関数は真の値を返し、対応する関数に渡される値を理解されよう。
3.スキーマクラスは、メソッドと、着信オブジェクトを検証します
スキーマはまた、クラスの数(使用、AND、OR、など)、また、例えば、スキーマのパラメータとして渡されたvalidateメソッドと、これらのクラスの例ですが構築されています。
from schema import Schema, And
# And代表两个条件必须同时满足
Schema(And(str, lambda s: len(s) > 2)).validate('abcd')
# 'abcd'
コンテナオブジェクトに4スキーマ求心性(リスト、タプル、設定、等)
例えば:
Schema([int, float]).validate([1, 2, 3, 4.0])
# [1, 2, 3, 4.0]
これは[1、2、3、4.0] int型であるか、またはジョブ(または音符との関係)を浮遊しなければならない任意の要素のために、対応します
5.スキーマは、辞書オブジェクトを渡す(シーンのほとんどのスキーマ辞書オブジェクトを使用して渡され、これは非常に重要です)
Schema({'name': str, 'age': int}).validate({'name': 'foobar', 'age': 18})
# {'age': 18, 'name': 'foobar'}
Schema({'name': str, 'age': int}).validate({'name': 'foobar'})
# SchemaMissingKeyError: Missing keys: 'age'
まず第一に、明確な二つの概念、モード辞書と呼ばれるスキーマの着信クラス辞書、辞書データ辞書と呼ばれるvaldiateの着信方法。
まず、スキーマは、パターン辞書やデータ・ディクショナリのキーがまったく同じではなく、同じことを直接スローするかどうかを判断します。あなたは、データ・ディクショナリの値はそれを確認することができた場合にのみ、例外をスローそうでない場合は、すべてのデータを返すために、対応する値モード辞書の値を確認するために、データ・ディクショナリを取得したい場合は、それのこの突然感じて新鮮な検証を感じていないですか?
6.よくある質問
6.1スキーマ着信辞書は非常に便利ですが、私のデータのいくつかは、いくつかのキーを行う方法を提供しない場合があること、オプションですか?
from schema import Optional, Schema
Schema({'name': str, Optional('age'): int}).validate({'name': 'foobar'})
# {'name': 'foobar'}
Schema({'name': str, Optional('age', default=18): int}).validate({'name': 'foobar'})
# {'age': 18, 'name': 'foobar'}
キーを入力することを禁止6.2:禁断
禁断のキーを禁止することができます。
from schema import Schema, Forbidden
Schema({Forbidden('name'): str, 'age': int}).validate({"age": 15}) # {"age": 15}
Schema({Forbidden('name'): str, 'age': int}).validate({"name": "laozhang", "age": 15}) # schema.SchemaForbiddenKeyError
Schema({Forbidden('name'): str, 'age': int}).validate({"name": 10, "age": 15}) # schema.SchemaWrongKeyError
却下されるかどうかを決定します無効に秘密鍵の値とペアになって、ことは注目に値します。
from schema import Schema, Forbidden
Schema({Forbidden('name'): int, 'name': str}).validate({'name': 'laozhang'}) # {'name': 'laozhang'}
Schema({Forbidden('name'): str, 'name': str}).validate({'name': 'laozhang'}) # schema.SchemaForbiddenKeyError
また、オプションよりも高い優先順位を禁止:
from schema import Schema, Forbidden, Optional
Schema({Forbidden('name'): str, Optional('name'): str}).validate({"name": "laozhang"}) # schema.SchemaForb
私は、着信データ・ディクショナリの唯一の6.3スキーマ検証の一部をしたい、あなたは余分なキーを持つことができますが、Baocuoは、どのように行うのではないのですか?
Schema({'name': str, 'age': int}, ignore_extra_keys=True).validate({'name': 'foobar', 'age': 100, 'sex': 'male'})
# {'age': 100, 'name': 'foobar'}
6.4スキーマスローされた例外情報は非常に友好的ではない、と私はエラーメッセージをカスタマイズしたい、どのようにしますか?
スキーマ独自のクラス(使用、AND、OR、正規表現、スキーマなど)はエラーメッセージをカスタマイズすることができ、パラメータエラーがあります
Schema({'name': str, 'age': Use(int, error='年龄必须是整数')}).validate({'name': 'foobar', 'age': 'abc'})
# SchemaError: 年龄必须是整数
6.5使用
検証の際に使用し、それは自動的にその値を変換するのに役立ちます
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
6.6のConst
私たちは、使用の検証時には、自動的にその値を変えるのを助けることがわかっています。constがオリジナルそのままを残すこと:
from schema import Schema, Use, Const
print Schema(Const(Use(int))).validate('10') # 10-->str类型
7.より複雑な例:
from schema import Schema, And, Optional, SchemaError, Regex
def name_check(name):
password_list = ["root", "admin", "888888", "baba", "aaaaaa", "112233"]
if name in password_list:
return False
return True
schema = {
"id": And(int, lambda x: 100 <= x, error="id必须是整数,大于等于100"),
"name": And(str, name_check, error="name已经存在"),
"price": And(float, lambda x: 111 > x > 0, error="price必须是大于0小于111的小数"),
"data": {
"password": And(Regex("[a-z0-9A-Z]{8,20}"), error="密码为数字、字母,长度8-20"),
"email": And(Regex("^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$"), error="email格式错误")
},
Optional("info", default="这个key可以不提供,我设置了这一段默认值。"): str,
}
data = {
"id": 111,
"name": "jarvis",
"price": 9.5,
"data": {
"password": "222agfwetAAA",
"email": "[email protected]",
}
}
try:
a = Schema(schema).validate(data)
except SchemaError as e:
print(e)
else:
print("验证成功!\n{}".format(a))
# 验证成功!
# {'id': 111, 'name': 'jarvis', 'price': 9.5, 'data': {'password': '222agfwetAAA', 'email': '[email protected]'}, 'info': '这个key可以不提供,我设置了这一段默认值。'}
参考記事:HTTPS://segmentfault.com/a/1190000011777230#articleHeader5