我覺得加載一些YAML對象是一個小小的誤解。我在下面定義了這個類。Python/YAML:如何在loadConfig中不僅從YAML文件初始化其他對象?
我想要做的是加載一些對象與覆蓋loadConfig
功能爲YAMLObjects
。其中一些來自我的.yaml
文件,但其他文件應該由從YAML文件加載的對象構建。
例如,在下面的類中,我加載了一個名爲「keep」的成員對象,它是一個字符串,命名了一些要保留在該區域中的項。但是我也想把它解析成一個列表,並將列表存儲爲一個成員對象。而且我不希望用戶必須在YAML中同時提供該參數的字符串和列表版本。
我目前的解決方法是覆蓋Region
中的__getattr__
函數,並使其創建默認值,如果它看起來沒有找到它們。但是,這僅僅是初始化對象的笨重和複雜。
我在這裏誤解了什麼約定。爲什麼loadConfig
方法不會創建YAML中找不到的其他內容?
import yaml, pdb
class Region(yaml.YAMLObject):
yaml_tag = u'!Region'
def __init__(self, name, keep, drop):
self.name = name
self.keep = keep
self.drop = drop
self.keep_list = self.keep.split("+")
self.drop_list = self.drop.split("+")
self.pattern = "+".join(self.keep_list) + "-" + "-".join(self.drop_list)
###
def loadConfig(self, yamlConfig):
yml = yaml.load_all(file(yamlConfig))
for data in yml:
# These get created fine
self.name = data["name"]
self.keep = data["keep"]
self.drop = data["drop"]
# These do not get created.
self.keep_list = self.keep.split("+")
self.drop_list = self.drop.split("+")
self.pattern = "+".join(self.keep_list) + "-" + "-".join(self.drop_list)
###
### End Region
if __name__ == "__main__":
my_yaml = "/home/path/to/test.yaml"
region_iterator = yaml.load_all(file(my_yaml))
# Set a debug breakpoint to play with region_iterator and
# confirm the extra stuff isn't created.
pdb.set_trace()
這裏是test.yaml
這樣你就可以運行所有的這一點,明白我的意思:
Regions:
# Note: the string conventions below are for an
# existing system. This is a shortened, representative
# example.
Market1:
!Region
name: USAndGB
keep: US+GB
drop: !!null
Market2:
!Region
name: CanadaAndAustralia
keep: CA+AU
drop: !!null
這裏,例如,是什麼樣子的我,當我在運行此IPython的殼和探索加載的對象:
In [57]: %run "/home/espears/testWorkspace/testRegions.py"
--Return--
> /home/espears/testWorkspace/testRegions.py(38)<module>()->None
-> pdb.set_trace()
(Pdb) region_iterator
<generator object load_all at 0x1139d820>
(Pdb) tmp = region_iterator.next()
(Pdb) tmp
{'Regions': {'Market2': <__main__.Region object at 0x1f858550>, 'Market1': <__main__.Region object at 0x11a91e50>}}
(Pdb) us = tmp['Regions']['Market1']
(Pdb) us
<__main__.Region object at 0x11a91e50>
(Pdb) us.name
'USAndGB'
(Pdb) us.keep
'US+GB'
(Pdb) us.keep_list
*** AttributeError: 'Region' object has no attribute 'keep_list'
我剛剛爲from_yaml()方法實現了這個。它工作得很好,但確實需要你在'__metaclass__ = yaml.YAMLObjectMetaclass'行下面提供yaml_tag。看來(通過查看[source](http://pyyaml.org/browser/pyyaml/trunk/lib/yaml/__init__.py#L282)),如果沒有yaml_tag,to_yaml()和from_yaml()aren不會自動加載。 – 2015-01-26 21:43:34