一個模式描述是它自己的語言,用它自己的語法,你必須學會的特質。如果您的要求發生變化,您必須維護您的YAML所針對的「程序」。
如果您已經在使用YAML並熟悉Python,則可以使用YAML的標記工具在分析時檢查對象。
假設你有一個文件input.yaml
:
successive:
worker:
cds_process_number: !nonneg 0
spider_interval: !pos 10
run_worker_sh: !path /home/lmakeev/CDS/releases/master/scripts/run_worker.sh
allow:
- !regex "*"
deny:
- !regex "^[A-Z]{3}_.+$"
,您可以創建並註冊使用以下program¹是檢查值的四個班(除去和標籤插入評論您的示例文件):
import sys
import os
import re
import ruamel.yaml
import pathlib
class NonNeg:
yaml_tag = u"!nonneg"
@classmethod
def from_yaml(cls, constructor, node):
val = int(node.value) # this creates/returns an int
assert val >= 0
return val
class Pos(int):
yaml_tag = u"!pos"
@classmethod
def from_yaml(cls, constructor, node):
val = cls(node.value) # this creates/return a Pos()
assert val > 0
return val
class Path:
yaml_tag = u"!path"
@classmethod
def from_yaml(cls, constructor, node):
val = pathlib.Path(node.value)
assert os.path.exists(val)
return val
class Regex:
yaml_tag = u"!regex"
def __init__(self, val, comp):
# store original string and compile() of that string
self._val = val
self._compiled = comp
@classmethod
def from_yaml(cls, constructor, node):
val = str(node.value)
try:
comp = re.compile(val)
except Exception as e:
comp = None
print("Incorrect regex", node.start_mark)
print(" ", node.tag, node.value)
return cls(val, comp)
yaml = ruamel.yaml.YAML(typ="safe")
yaml.register_class(NonNeg)
yaml.register_class(Pos)
yaml.register_class(Path)
yaml.register_class(Regex)
data = yaml.load(pathlib.Path('input.yaml'))
個人from_yaml
classmethods中的實際檢查應該適合您的需要(我必須刪除Path的斷言,因爲我沒有該文件)。
如果你運行上面的你會注意它打印:
Incorrect regex in "input.yaml", line 7, column 9
!regex *
因爲"*"
不是有效的正則表達式。您的意思是:".*"
?
¹這是使用ruamel.yaml,一個YAML 1.2分析器,其中我的作者來完成。您可以使用PyYAML實現相同的結果,例如通過子類化ObjectDict
(默認情況下不安全,因此請確保在代碼中正確)
可能會詳細說明一點。你爲什麼認爲棉花糖不是正確的工具?現在這是非常開放的。 – Grimmy
由於非常複雜的結構架構難以閱讀,我不需要序列化的設置,想要的東西像xsd – Helvdan
這樣的事情?:https://github.com/Julian/jsonschema – Grimmy