Python: Exception in the separated module works wrong에서 다양한 용도의 GnuLibError 클래스를 사용하여 다양한 오류를 '대기'합니다. 각 하위 오류는 고유 한 ID 번호와 오류 형식 문자열을가집니다. - 오류 번호를 호출하는 경우팩토리 클래스, 서브 클래스 생성자에 전달되는 인수의 수가 잘못되었습니다.
class GNULibError(Exception):
sub_exceptions = 0 # patched with dict of subclasses once subclasses are created
err_num = 0
err_format = None
def __new__(cls, *args):
print("new {}".format(cls)) # DEBUG
if len(args) and args[0] in GNULibError.sub_exceptions:
print(" factory -> {} {}".format(GNULibError.sub_exceptions[args[0]], args[1:])) # DEBUG
return super(GNULibError, cls).__new__(GNULibError.sub_exceptions[args[0]], *(args[1:]))
else:
print(" plain {} {}".format(cls, args)) # DEBUG
return super(GNULibError, cls).__new__(cls, *args)
def __init__(self, *args):
cls = type(self)
print("init {} {}".format(cls, args)) # DEBUG
self.args = args
if cls.err_format is None:
self.message = str(args)
else:
self.message = "[GNU Error {}] ".format(cls.err_num) + cls.err_format.format(*args)
def __str__(self):
return self.message
def __repr__(self):
return '{}{}'.format(type(self).__name__, self.args)
class GNULibError_Directory(GNULibError):
err_num = 1
err_format = "destination directory does not exist: {}"
class GNULibError_Config(GNULibError):
err_num = 2
err_format = "configure file does not exist: {}"
class GNULibError_Module(GNULibError):
err_num = 3
err_format = "selected module does not exist: {}"
class GNULibError_Cache(GNULibError):
err_num = 4
err_format = "{} is expected to contain gl_M4_BASE({})"
class GNULibError_Sourcebase(GNULibError):
err_num = 5
err_format = "missing sourcebase argument: {}"
class GNULibError_Docbase(GNULibError):
err_num = 6
err_format = "missing docbase argument: {}"
class GNULibError_Testbase(GNULibError):
err_num = 7
err_format = "missing testsbase argument: {}"
class GNULibError_Libname(GNULibError):
err_num = 8
err_format = "missing libname argument: {}"
# patch master class with subclass reference
# (TO DO: auto-detect all available subclasses instead of hardcoding them)
GNULibError.sub_exceptions = {
1: GNULibError_Directory,
2: GNULibError_Config,
3: GNULibError_Module,
4: GNULibError_Cache,
5: GNULibError_Sourcebase,
6: GNULibError_Docbase,
7: GNULibError_Testbase,
8: GNULibError_Libname
}
이 공장 클래스로 GNULibError로 시작 :
나는 그것이 더 나은 예외 클래스의 계층 구조로 작성하고, 그렇게에 착수 할 것입니다 생각 인식 된 서브 클래스에 속한 경우 해당 서브 클래스에 속한 객체를 리턴하고, 그렇지 않으면 디폴트 오류 유형으로 자신을 리턴합니다.
이 코드를 바탕으로, 다음과 정확히 상응하는 (그러나 아니다)해야합니다
e = GNULibError(3, 'missing.lib')
f = GNULibError_Module('missing.lib')
print e # -> '[GNU Error 3] selected module does not exist: 3'
print f # -> '[GNU Error 3] selected module does not exist: missing.lib'
내가 몇 가지 전략적 인쇄 문을 추가하고, 오류가
GNULibError.__new__
것 같다 :
>>> e = GNULibError(3, 'missing.lib')
new <class '__main__.GNULibError'>
factory -> <class '__main__.GNULibError_Module'> ('missing.lib',) # good...
init <class '__main__.GNULibError_Module'> (3, 'missing.lib') # NO!
^
why?
하위 클래스 생성자를 subclass.__new__(*args[1:])
으로 호출합니다. 하위 클래스 ID 3을 삭제해야하지만 아직 __init__
은 여전히 3을 얻고 있습니다! subclass.__init__
으로 전달되는 인수 목록을 어떻게 트리밍 할 수 있습니까?