Quand j'ai cherché, il n'y avait pas d'échantillons (même dans les pays anglophones!), Donc c'était facile.
J'écrivais du code en Python qui définit le comportement d'un programme en YAML, et je voulais juste écrire un processus pour créer un objet en YAML.
Pour autant que je puisse voir PyYAMLDocumentation, il y a une ** balise **, qui semble faire ce que je veux, mais il n'y a aucun exemple d'utilisation nulle part. Je ne sais pas s'il doit être utilisé ni comment le définir. Eh bien, j'étais en difficulté.
Alors, du coup, c'est le sujet principal. Pour ajouter une balise, transmettez une valeur à la fonction globale du module PyYAML, ʻadd_multi_constructor () `.
yaml.add_multi_constructor("tag:yaml.org,2002:var", var_handler)
# ...
def var_handler(loader, suffix, node=None):
#En traitement
Si vous écrivez un tel code, il réagira lorsque le fichier YAML aura la balise suivante et var_handler
sera appelé.
textvariable: !!var:StringVar
name: label
default: ""
Trois paramètres sont passés à la fonction spécifiée dans l'argument
: StringVar
MappingNode (value = [(ScalarNode (), ScalarNode ()), (ScalarNode (), ScalarNode ())])
Ainsi, si vous renvoyez une valeur comme valeur de retour de la fonction, la partie balise sera la valeur spécifiée pour la valeur de retour. Par exemple, dans l'exemple ci-dessus, renvoyer le mot «Oui» équivaut à écrire «textvariable: Yes».
ʻAdd_multi_constructor () `Si vous suivez le comportement de la fonction, si vous omettez le Loader défini comme argument de mot-clé, la fonction spécifiée ici semble être ajoutée aux trois classes Loader, FullLoader et UnsafeLoader. Donc, si vous utilisez SafeLoader **, peu importe ce que vous faites ici, aucune fonction ne sera ajoutée. ** **
Lors du chargement de YAML, si vous souhaitez charger uniquement les balises que vous avez définies vous-même, vous pouvez ajouter une fonction en spécifiant SafeLoader comme argument.
J'avais un autre processus et je me sentais un peu inquiet de jouer directement avec SafeLoader, alors j'ai défini une nouvelle classe qui a hérité de SafeLoader.
class GeneratorLoader(yaml.SafeLoader):
def __init__(self, stream):
super().__init__(stream)
yaml.add_multi_constructor("tag:yaml.org,2002:var", GeneratorLoader.var_handler,
Loader=GeneratorLoader)
@staticmethod
def var_handler(loader, suffix, node=None):
pass
Si vous utilisez la classe créée ici comme Loader dans la méthode yaml.load ()
, les balises seront traitées.
Notez que les fonctions définies dans \ _ \ _ init \ _ \ _. Py de PyYAML telles que yaml.load ()
n'ont pas de fonction qui reçoit une instance de Loader (toutes reçoivent des classes).
Par conséquent, si vous souhaitez utiliser l'objet Loader créé ci-dessus après le chargement de YAML, vous devez appeler Loader # get_single_data ()
directement.
loader = GeneratorLoader(self.string)
struct = loader.get_single_data()
Je travaille dessus maintenant, mais je l'utilise dans le module suivant.
Depuis le 21 septembre 2020, il existe un tel processus dans tksugar / generator.py
(peut déplacer le code plus tard).
Recommended Posts