우선 : abc
모듈을 잘못 사용하고 있습니다 (see the docs). 수업 A
은 abc.ABCMeta
의 메타 클래스를 가져야합니다. 그래서 이미 메타 클래스를 사용하고 있다면 그것을 당신의 장점으로 확장 할 수 있습니다.
abstractmethod
작동하도록 abc.ABCMeta
에서 상속 및 do_thing
장식 메타 클래스 :
# class Abstract(metaclass=ABCMeta): in python3
class Abstract(object):
__metaclass__ = DecoratingMeta # remove this line in python3
@abstractmethod
def do_thing(self, input):
pass
@classmethod
def do_thing_decorator(cls, function):
return function # default decorator that does nothing
참고 do_thing_decorator
: 아무것도하지 기본 체크 장식과 함께 이제 추상 기본 클래스를
from abc import ABCMeta, abstractmethod
class DecoratingMeta(ABCMeta):
def __new__(cls, *args):
new_class = super(DecoratingMeta, cls).__new__(cls, *args)
# decorating do_thing manually
new_class.do_thing = new_class.do_thing_decorator(new_class.do_thing)
return new_class
을 이 경우 클래스 메소드 여야합니다. python3
및 python2
에서 작동하는 메타 클래스의 경우 six을 참조하십시오. 단지 특정 검사를 구현하지만 여전히 추상적 인
귀하의 검사 클래스 : 당신이 check = do_thing_func(input)
을 쓴 라인은 재귀 오류가 발생할 것이라고
class Checker(Abstract):
@classmethod
def do_thing_decorator(cls, function):
def do_checked_thing(self, input):
check = function(self, input) # NOT self.do_thing(input) else recursion error
if check != 1:
raise ValueError("Check failed")
return check
return do_checked_thing
참고.
그리고 do_thing
의 샘플 구현하여 구체적인 클래스 :
class Concrete(Checker):
def do_thing(self, input):
return input # sample implementation
당신은 do_thing(1)
성공 확인할 수 있습니다 및 do_thing(2)
이 방식의 단점은 당신이 할 수 없다는 것입니다
c = Concrete()
c.do_thing(1)
try:
c.do_thing(2)
except ValueError:
print("check failed")
실패 do_thing_decorator
개요.
그래서이 이미 많은 텍스트,하지만 당신은 전혀 메타 클래스를 사용하지 않으려면 훨씬 더 간단한 방법이있다 :
하여 do_thing
방법의 검사를 수행하는 클래스를 작성 이 "추상적"방법을 사용하여 : do_thing_func
및 check_do_thing
정말 추상적하지 않은 것을
class Abstract(object):
def do_thing_func(self, input):
raise NotImplementedError()
def check_do_thing(self, result):
raise NotImplementedError()
# don't override this method
def do_thing(self, input):
result = self.do_thing_func(input)
self.check_do_thing(result) # may raise
return result # if it does not raise return the result
참고하면 유형 Abstract
의 아직 실체화 객체를 할 수 있습니다. 당신이 추상적 인 것을 원한다면 표준 abc.ABCMeta
메타 클래스를 여기에 사용하십시오.
지금 우리가 여기에 장식을 필요로하지 않기 때문에 훨씬 간단하게 check_do_thing
class Checker(Abstract):
def check_do_thing(self, result):
if result != 1:
raise ValueError("check failed")
구현하는 검사 클래스를 만들 수 있습니다.
그리고 Concrete
지금 do_thing_func
를 구현해야하지만이 클래스를 사용할 때 do_thing
를 호출해야한다는 do_thing_func
가
class Concrete(Checker):
def do_thing_func(self, input):
return input # sample implementation
참고 구현 마지막으로 구상 클래스
.
여기서 단점은 do_thing
을 무시하고 검사를 위반할 수 있다는 것입니다.
'__new __()'메소드를 보셨습니까? –
@ IgnacioVazquez-Abrams는 불합리한 해결책이 아닙니다. 메소드 레벨에서 좀 더 직관적 인 것을 기대하고 있었지만, 뭔가 더 좋은 것을 찾을 수 없다면 아마도 디폴트가 될 것입니다. –