2017-03-31 1 views
0

XML 문서 모음을 HTML로 변환하는 프로그램을 작성 중입니다. 문서는 유사하지만 동일하지 않은 변환을 필요로하므로 대부분의 세부 사항을 일반 BaseParser 클래스로 추상화 한 다음 문서 별 변환을 캡슐화하는 각 문서에 대해 하나의 서브 클래스를 작성하기를 원합니다. 이벤트 기반 구문 분석을 위해 Python 표준 라이브러리 xml.etree.ElementTree 패키지를 사용하고 있습니다.어떻게 파이썬에서 클래스 변수에 메소드를 등록 할 수 있습니까?

나는이 같은 코드를 작성할 수 있기를 바란다. 함수의 로직이 호출되어야 할 때 번들로 묶여있다. 이 작업을 위해 (각 인스턴스는 자신의 복사본을 가지고하는 것이 중복 될 것이지만, 또는 인스턴스 변수)

class CustomParser(BaseParser): 
    @on_tag('word', {'lang':'en'}) 
    def found_en_word(self, tag, attrs): 
     # do something 

는 장식의 요구는되도록 제어 흐름이 할 수있는, 클래스 변수에 found_en_word 함수를 등록 BaseParser 클래스에서 분리 될 수 있습니다.

현재 나와있는 해결책은 메타 클래스를 사용하여 클래스에 callbacks 사전을 만드는 것입니다. 메타 클래스는 내가 기대했던 방법을 상속처럼

class Meta(type): 
    def __new__(cls, clsname, bases, dct): 
     callbacks = {} 
     for key, value in dct.items(): 
      if hasattr(value, '_on_tag'): 
       callbacks[value._on_tag] = value 
     ret = type(clsname, bases, dct) 
     ret.callbacks = callbacks 
     return ret 

def on_tag(tag, attrs=None): 
    def decorator(f): 
     f._on_tag = (tag, attrs) 
     return f 
    return decorator 

class BaseParser(metaclass=Meta): 
    ... 

불행히도 그것은 보이지 않는 : 메타 클래스는이 CustomParser 그냥 일반적으로 상속받는 BaseParser 클래스를 수정 구성하는 데 사용되는 것 같다.

이 구성은 메타 클래스 유무에 상관없이 파이썬에서 구현할 수 있습니까?

답변

1

메타 클래스가 클래스를 올바르게 구성하지 않습니다. the docs에 설명 된 바와 같이 type.__new__(Meta, clsname, bases, dct)으로 전화해야합니다. type(clsname, bases, dct)을 호출하면 사용자 정의 메타 클래스의 인스턴스가 아닌 일반 클래스가 생성됩니다.

수정하면 _on_tag을 사전 키로 사용하려고하지만 _on_tag에는 사전이 포함되어 있고 사전은 해시 가능하지 않은 또 다른 문제가 있습니다. 그것은 당신의 주된 질문에 약간 접선이지만, 아마도 사용자가 @on_tag('word', {'lang': 'en'}) 대신에 @on_tag('word', ('lang', 'en'))을하도록함으로써 그것을 처리 할 방법을 찾아야 할 것입니다.

+0

원래의 문제와 제가 모르는 문제를 모두 해결 한 좋은 캐치! 데코레이터를 사용하여 사전을 터플로 변환하여 더 나은 호출 구문을 유지할 수 있습니다. – iafisher

관련 문제