2013-01-10 2 views
4

필자가 작업 한 특정 응용 프로그램의 구성 파일에서 잘 정의 된 구조를 활용하는 매우 전문화 된 파서를 작성하는 ConfigParser 모듈의 동작을 모방합니다. 파일은 표준 INI 구조를 따릅니다.__setattr__을 부분적으로 무시할 수 있습니까?

[SectionA] 
key1=value1 
key2=value2 

[SectionB] 
key3=value3 
key4=value4 

내 응용 프로그램의 경우 섹션은 크게 관련이 없습니다. 다른 섹션의 키 사이에 겹침이 없으며 모든 사용자는 키 이름 만 기억합니다. 어떤 섹션도 들어 가지 않습니다. 따라서 내가 만들고있는 클래스 에서 __getattr____setattr__을 덮어 쓰고 싶습니다. 다음과 같이 바로 가기를 할 수 있도록 :

config = MyParser('myfile.cfg') 
config.key2 = 'foo' 

__setattr__ 방법은 첫째 key2라는 섹션을 찾아 존재하는 경우 '갑'에 그 설정하려고합니다. 그러한 섹션이 없다고 가정하면 각 섹션 내부에 key2이라는 키가 들어 있습니다. 키가 존재하면 새로운 값으로 설정됩니다. 존재하지 않으면 파서가 마침내 AttributeError을 발생시킵니다.

이 테스트 구현을 구축했지만 문제는이 동작에서 면제 된 몇 가지 똑 바른 업 속성도 필요하다는 것입니다. config.filename은 원본 파일의 이름을 포함하는 간단한 문자열이고 각 섹션의 사전을 보유하는 사전은 config.content입니다.

생성자의 filenamecontent 속성을 사용자 정의 게터 및 설정자가 간과하지 않도록 명확하게 설정할 수 있습니까? 파이썬은 사용자 정의 __setattr__을 호출하기 전에 객체의 __dict__에서 속성을 찾습니다. 슈퍼 클래스에

답변

5

패스 filename, content

class MyParser(object): 
    def __setattr__(self, k, v): 
     if k in ['filename', 'content']: 
      super(MyParser, self).__setattr__(k, v) 
     else: 
       # mydict.update(mynewattr) # dict handles other attrs 
+0

나는 "이들의 목록을 유지해야하는 아이디어를 좋아하지 않는다 :

귀하의 질문에 대답하기 위해이 같은으로 구현할 수 있도록 __setattr__()는 이전 __dict__에서 확인하기 위해 호출된다 특수한 "속성을'__setattr__' 메소드에 추가합니다. 당신의'super' construction을 사용하여 생성자에서 이것을 정의 할 수있는 것처럼 보입니다. 'print config.filename'은 올바른 일을합니다. 그러나 속성을 설정하는 것은 커스텀'__setattr__'으로 내려 가서 던지고 에러를 끝내기 때문에 작동하지 않습니다. 왜 파이썬은 속성을 가져올 때 붙잡습니까? –

+1

'__setattr__'에서 정의하고 싶지 않다면 (예 : 리터럴 목록 대신에'MyParser.specials '와 같이) 항상 클래스 속성을 정의 할 수 있지만 코드의 흐름은 동일합니다. 왜 작품을 얻는가에 관해서는'__getattr__'가이 예제에서 정의되지 않았기 때문 만 아닌가요? – Cartroo

+0

@Cartroo 실제로 실제로 이러한 방법을 구현 한 곳에서 직접 테스트를 수행했습니다. 왜냐하면'return' 문장이 실행을 끝내지 않고 변수를 설정하는 곳에서'return' 문장이'__setattr__'으로 코드의 실행을 끝낸'__getattr__' 논리를 복제했기 때문이라고 밝혀졌습니다. 그래서 필자가 인식 한 차이점은 기본적인 파이썬 동작보다는 제 버그였습니다. –

2

나는 파일의 내용에 대한 사전과 같은 인터페이스를 제공하고 내부 목적을 위해 액세스 속성 떠날 청소기 것 같아요 처리합니다. 그러나 그건 내 의견이다.

class MyParser(object): 

    specials = ("filename", "content") 

    def __setattr__(self, attr, value): 
     if attr in MyParser.specials: 
      self.__dict__[attr] = value 
     else: 
      # Implement your special behaviour here 
관련 문제