2009-06-17 8 views
0

파이썬에서 내부 XML 기반 메타 데이터 형식에 대한 파서를 작성하고 있습니다. 다른 태그를 처리하기 위해 다른 클래스를 제공해야합니다. 다소 큰 핸들러 컬렉션이 필요하기 때문에 간단한 플러그인 시스템으로 생각했습니다. 내가 원하는 것은 모든 클래스를 패키지에로드하고 그것을 파서에 등록하는 것입니다. 나의 현재의 시도는 다음과 같습니다
간단한 파이썬 플러그인 시스템

class MetadataParser: 
    def __init__(self): 
     #... 
     self.handlers={} 
     self.currentHandler=None 
     for handler in dir(Handlers): # Make a list of all symbols exported by Handlers 
      if handler[-7:] == 'Handler': # and for each of those ending in "Handler" 
       handlerMod=my_import('MetadataLoader.Handlers.' + handler) 
       self.registerHandler(handlerMod, handlerMod.tags) # register them for their tags 

    # ... 

    def registerHandler(self, handler, tags): 
     """ Register a handler class for each xml tag in a given list of tags """ 
     if not isSequenceType(tags): 
      tags=(tags,) # Sanity check, make sure the tag-list is indeed a list 
     for tag in tags: 
      self.handlers[tag]=handler 

그러나이 작동하지 않습니다 (핸들러는 핸들러가 포함 된 패키지입니다, 각 핸들러는 문자열의 튜플 인 정적 멤버 태그가). 오류가 발생합니다. AttributeError: 'module' object has no attribute 'tags' 무엇이 잘못 되었나요?

+1

들여 쓰기를 수정했습니다. – SilentGhost

+1

실제로 많은 정보를 제공하지 않습니다. 오류 메시지는 아마도 * 오류가 발생한 행 *에서 문제를 정확하게 지적하는 데 도움이 될 것입니다. 또한 코드에는 구문 오류 (클래스 이름 뒤에 콜론이 누락 됨)가 있기 때문에 여기에 게시 한 내용이 전혀 실행되지 않습니다. 또한 오류는 게시하지 않은 코드의 일부분 일 수 있습니다. – sth

답변

0

먼저 형식이 잘못되었거나 잘못된 코드에 사과드립니다.
보고 주셔서 감사합니다. 그러나 범인은 종종 의자와 키보드 사이에있었습니다. 나는 같은 이름의 클래스와 모듈을 가짐으로써 혼란 스러웠다. my_import의 결과 (이제는 내가 어디에서 왔는지도 언급하지 않았다는 것을 깨닫습니다. SO : link)는 areaHandler라는 이름의 모듈입니다. areaHandler라는 클래스도 필요합니다. 그래서 나는 eval ('Handlers.'+ handler + '.'+ handler) 클래스를 골라 내야 만했다.
시간 내 주셔서 감사 드리며 대역폭에 대해 사과드립니다.

+0

'eval'은 동적으로 속성을 가져 오는 훌륭한 방법은 아닙니다. 이를 수행하는 일반적인 방법은'getattr (getattr (Handlers, handler), handler)'입니다. – Ben

0

아마도 handlerMod 모듈 중 하나에 tags 변수가 포함되어 있지 않습니다.

0

this page의 예제와 설명을 읽고 플러그인 아키텍처를 작성하는 방법을 설명하는 것이 좋습니다.

0

extend_me 라이브러리를 통해 간단하고 완벽하게 확장 가능한 구현이 가능합니다. 자세한 내용은 documentation 또는 code보고 들어

코드

from extend_me import ExtensibleByHash 

# create meta class 
tagMeta = ExtensibleByHash._('Tag', hashattr='name') 

# create base class for all tags 
class BaseTag(object): 
    __metaclass__ = tagMeta 

    def __init__(self, tag): 
     self.tag = tag 

    def process(self, *args, **kwargs): 
     raise NotImeplemntedError() 

# create classes for all required tags 
class BodyTag(BaseTag): 
    class Meta: 
     name = 'body' 

    def process(self, *args, **kwargs): 
     pass # do processing 

class HeadTag(BaseTag): 
    class Meta: 
     name = 'head' 

    def process(self, *args, **kwargs): 
     pass # do some processing here 

# implement other tags in this way 
# ... 

# process tags 
def process_tags(tags): 
    res_tags = [] 
    for tag in tags: 
     cls = tagMeta.get_class(tag) # get correct class for each tag 
     res_tags.append(cls(tag)) # and add its instance to result 
    return res_tags 

처럼 보일 수 있습니다. 이 lib 디렉토리는에서 사용됩니다 OpenERP/Odoo RPC lib