2012-11-08 2 views
6

yaml.load에 의해 호출 항목()의 제어 순서 :PyYAML : 나는 DB에서 일부 레코드를 생성하는 YAML 설정 파일이

setting1: 
    name: [item,item] 
    name1: text 
anothersetting2: 
    name: [item,item] 
    sub_setting: 
     name :[item,item] 

내가 setting3이 파일을 업데이트하고 DB의 레코드를 재생 기준 :

import yaml 
fh = open('setting.txt', 'r') 
setting_list = yaml.load(fh) 
for i in setting_list: 
    add_to_db[i] 

가) (그 순서 설정 (DB에서 ID 번호)를 DB로 addig 메신저와 같은 각각의 시간을 머물 ... 그리고 setting3 그냥 yaml.load에 추가됩니다 것이 중요합니다 그것의 id가 이미 i 인 어떤 레코드도 혼동하지 않도록 n db ... 지금마다 다른 설정을 추가하고 yaml.load() 레코드를 호출 할 때마다 레코드가 다른 순서로로드되어 다른 ID가 생성됩니다. 내가 팁 abarnert 을 따라이 요점 https://gist.github.com/844388

했다 한 작품 기대 감사로 :)

편집, 나는 어떤 아이디어를 환영!

+0

먼저 이 'PyYAML' 또는 다른 것? 내장 된'yaml' 모듈과'yaml' 모듈을 제공하는 적어도 두 개의 PyPI 패키지는 없습니다. 일반적으로 타사 모듈을 사용할 때마다 어디에서 가져 왔는지 말해야합니다. – abarnert

+0

당신이 사용하고있는 모듈이 무엇이든, 매핑 노드를 파이썬으로 변환하는 방식을 후킹해야하므로'dict' 대신'collection.OrderedDict'를 사용합니다. PyYAML 외에 다른 모듈들과 함께, 나는 잘 모른다. 'PyYAML'으로, 이것은 가능하지만, 당신이 고수준의 편리한 방법을 고수한다면 복잡합니다. 다른 곳에서는 의도 된 고리를 사용하는 것보다 그것을 monkeypatch하는 것이 더 쉬웠다 고 언급 한 사람이 있습니다. – abarnert

+0

이 질문의 제목으로 PyYAML을 사용하면 ... -> PyYAML : yaml.load()에 의해 호출 된 항목의 순서를 제어하십시오. 조언 해 주셔서 감사합니다. – zzart

답변

4

YAML 사양에서는 매핑의 주요 순서가 신뢰할 수없는 "표현 세부 정보"라고 분명하게 말합니다. 따라서 설정 파일은 매핑에 의존하는 경우 이미 유효하지 않으며 가능한 경우 유효한 YAML을 사용하는 것이 훨씬 낫습니다.

물론 YAML은 확장 가능하며 설정 파일에 "정렬 된 매핑"유형을 추가하는 것을 막을 수있는 방법은 없습니다. 예를 들어 :

!omap setting1: 
    name: [item,item] 
    name1: text 
!omap anothersetting2: 
    name: [item,item] 
    !omap sub_setting: 
     name :[item,item] 

당신은 당신이 사용중인 yaml 모듈 언급하지 않았다. 표준 라이브러리에는 그러한 모듈이 없으며, PyPI에 패키지가 2 개 이상있어 그 이름을 가진 모듈을 제공합니다. 그러나, 나는 이것이 가장 인기가 많기 때문에 PyYAML이라고 생각할 것입니다.

위에서 설명한 확장은 PyYAML로 구문 분석하기 쉽습니다.

{'anothersetting2': {'name': ['item', 'item'], 
    'sub_setting': 'name :[item,item]'}, 
'setting1': {'name': ['item', 'item'], 'name1': 'text'}} 

당신이 얻을 것이다 : 대신, 이제

def omap_constructor(loader, node): 
    return loader.construct_pairs(node) 
yaml.add_constructor(u'!omap', omap_constructor) 

: http://pyyaml.org/ticket/29 참조

(('anothersetting2', (('name', ['item', 'item']), 
    ('sub_setting', ('name, [item,item]'),))), 
('setting1', (('name', ['item', 'item']), ('name1', 'text')))) 

물론 이것은 당신에게 키 - 값 tuple s의 tuple을 제공하지만, 당신은 쉽게 construct_ordereddict를 쓸 수 있고 대신 OrderedDict을 얻을 수 있습니다. 입력뿐만 아니라 출력해야하는 경우 OrdereredDict 객체를 저장하는 표현자를 !omap으로 쓸 수도 있습니다. 당신이 정말로 그것을 대신 기본 매핑을위한 dictOrderedDict를 사용하기 위해 PyYAML 후크 할 경우를 고수하려는 경우

, 그것은 이미 파서 객체에서 직접 작업하는 경우 수행 아주 쉽게,하지만 더 어렵다 높은 수준의 편리한 방법. 다행히도 위의 링크 된 티켓에는 사용할 수있는 구현이 있습니다.실제 YAML을 더 이상 사용하지 않고 변종이므로 파일을 처리하는 다른 소프트웨어가 중단 될 수 있으며 가능성이 높습니다.

0

마지막으로, PyYAML은 이것을 지원하지 않았지만, 사전이나 사전 형 객체를 시작점으로 받아들이도록 수정하는 것이 쉽습니다.

+0

이것은 실제로 작동하지 않습니다. 첫째, YAML 문서는 사전 일 필요는 없습니다. 둘째로, 'OrderedDict'로 시작한다면, 모든 하위 사전은 여전히 ​​'dict'이 될 것입니다. 그래서 당신이 정말로 필요로하는 것은'dict' 대신에 다른 생성자를 받아들이도록 수정하는 것입니다 (그리고 이상적으로 다른 생성자는 종종 유용하지는 않지만 사용하는 각 생성자에 대해 하나씩). – abarnert

3

이제 ruaml.yaml을 사용할 수 있습니다. https://pypi.python.org/pypi/ruamel.yaml에서

:

ruamel.yaml는 단일 주어진를 들어 YAML 파서/주석, 서열 /지도 흐름 스타일의 왕복 보존을 지원 에미 터 및지도 키 위해

0

입니다 주문 된 사전으로 알려진 항목은 목록의 항목을 만들고 컬렉션을 사용합니다. 주문 처리 :

setting1: 
    - name: [item,item] 
    - name1: text 
anothersetting2: 
    - name: [item,item] 
    - sub_setting: 
     name :[item,item] 

import collections 
import yaml 
fh = open('setting.txt', 'r') 
setting_list = yaml.load(fh) 

setting1 = collections.OrderedDict(list(x.items())[0] for x in setting_list['setting1']) 
관련 문제