2011-08-28 13 views
10

में डिफ़ॉल्ट कन्स्ट्रक्टर पैरामीटर मैं यह नहीं ढूंढ पा रहा हूं कि यह PyYAML दस्तावेज़ में कैसे करें। मैं वाईएएमएल में परिभाषित पायथन कक्षाओं का प्रतिनिधित्व करना चाहता हूं, और कन्स्ट्रक्टर में पैरामीटर को दिया गया डिफ़ॉल्ट मान है यदि यह वाईएएमएल में निर्दिष्ट नहीं है। उदाहरण के लिए:pyyaml ​​

>>> class Test(yaml.YAMLObject): 
...  yaml_tag = u"!Test" 
...  def __init__(self, foo, bar=3): 
...    self.foo = foo 
...    self.bar = bar 
...  def __repr__(self): 
...    return "%s(foo=%r, bar=%r)" % (self.__class__.__name__, self.foo, self.bar) 
... 
>>> yaml.load(""" 
... --- !Test 
... foo: 5 
... """) 
Traceback (most recent call last): 
    File "<stdin>", line 4, in <module> 
    File "<stdin>", line 7, in __repr__ 
AttributeError: 'Test' object has no attribute 'bar' 

मैं उम्मीद है कि यह बार = 3 के साथ एक टेस्ट वस्तु बनाने होगा, लेकिन मैं इसे अपने निर्माता नजरअंदाज जब यह वस्तु बनाता है लगता है। अगर मैं YAML में बार के लिए एक मानचित्रण में शामिल हैं, सब कुछ उम्मीद के रूप में काम करता है:

>>> yaml.load(""" 
... --- !Test 
... foo: 5 
... bar: 42 
... """) 
Test(foo=5, bar=42) 

किसी को भी पता है कि कैसे मैं यह एक डिफ़ॉल्ट मान का उपयोग हो सकता है?

उत्तर

9

मुझे एक ही समस्या का सामना करना पड़ा: yaml_tag किसी कारण से काम नहीं करता है।

import yaml 

def constructor(loader, node) : 
    fields = loader.construct_mapping(node) 
    return Test(**fields) 

yaml.add_constructor('!Test', constructor) 

class Test(object) : 
    def __init__(self, foo, bar=3) : 
     self.foo = foo 
     self.bar = bar 
    def __repr__(self): 
     return "%s(foo=%r, bar=%r)" % (self.__class__.__name__, self.foo, self.bar) 

print yaml.load(""" 
- !Test { foo: 1 } 
- !Test { foo: 10, bar: 20 }""") 

आउटपुट:: तो मैं वैकल्पिक दृष्टिकोण का इस्तेमाल किया

[Test(foo=1, bar=3), Test(foo=10, bar=20)] 
0

alexanderlukanin13 के जवाब के आधार पर। यहाँ मेरा कट है।

import yaml 

YAMLObjectTypeRegistry = {} 

def register_type(target): 
    if target.__name__ in YAMLObjectTypeRegistry: 
     print "{0} already in registry.".format(target.__name__) 
    elif 'yaml_tag' not in target.__dict__.keys(): 
     print target.__dict__ 
     raise TypeError("{0} must have yaml_tag attribute".format(
      target.__name__)) 
    elif target.__dict__['yaml_tag'] is None: 
     pass 
    else: 
     YAMLObjectTypeRegistry[target.__name__] = target 
     yaml.add_constructor(
       target.__dict__['yaml_tag'], 
       lambda loader, node: target(**loader.construct_mapping(node))) 
     print "{0} added to registry.".format(target.__name__) 

class RegisteredYAMLObjectType(type): 
    def __new__(meta, name, bases, class_dict): 
     cls = type.__new__(meta, name, bases, class_dict) 
     register_type(cls) 
     return cls 

class RegisteredYAMLObject(object): 
    __metaclass__=RegisteredYAMLObjectType 
    yaml_tag = None 

फिर आप इसे इस तरह उपयोग कर सकते हैं:

class MyType(registry.RegisteredYAMLObject): 
    yaml_tag = u'!mytype' 
    def __init__(self, name, attr1='default1', attr2='default2'): 
     super(MyType, self).__init__() 
     self.name = name 
     self.attr1 = attr1 
     self.attr2 = attr2 
संबंधित मुद्दे