Python 具有不同特定消息的相同异常
我试图编写一个代码来区分以下四种不同的错误Python 具有不同特定消息的相同异常,python,error-handling,python-3.4,Python,Error Handling,Python 3.4,我试图编写一个代码来区分以下四种不同的错误 TypeError:第一个参数不是整数 TypeError:第二个参数不是字符串 ValueError:第一个参数的值不在1到13的范围内;或 ValueError:第二个参数的值不是集合{'s',h',c',d}中的字符串之一 但是,我只能使第一个错误生效,而不能使其他三个错误生效。我尝试了不同的方法使它工作,但仍然不能找出什么是错误的 class Card: # One object of class Card represents a playi
TypeError
:第一个参数不是整数李>
TypeError
:第二个参数不是字符串李>
ValueError
:第一个参数的值不在1
到13
的范围内;或ValueError
:第二个参数的值不是集合{'s',h',c',d}
中的字符串之一class Card: # One object of class Card represents a playing card
rank = ['','Ace','Two','Three','Four','Five','Six','Seven','Eight','Nine','Ten','Jack','Queen','King']
suit = {'d':'Diamonds', 'c':'Clubs', 'h':'Hearts', 's':'Spades'}
def __init__(self, rank=2, suit=0): # Card constructor, executed every time a new Card object is created
if type(rank) != int:
raise TypeError()
if type(suit) != str:
raise TypeError()
if rank != self.rank:
raise ValueError()
if suit != 'd' or 'c' or 'h' or 's':
raise ValueError()
self.rank = rank
self.suit = suit
def getRank(self): # Obtain the rank of the card
return self.rank
def getSuit(self): # Obtain the suit of the card
return Card.suit[self.suit]
def bjValue(self): # Obtain the Blackjack value of a card
return min(self.rank, 10)
def __str__(self): # Generate the name of a card in a string
return "%s of %s" % (Card.rank[int(self.rank)], Card.suit[self.suit])
if __name__ == "__main__": # Test the class Card above and will be skipped if it is imported into separate file to test
try:
c1 = Card(19,13)
except TypeError:
print ("The first parameter is not an integer")
except TypeError:
print ("The second parameter is not a string")
except ValueError:
print ("The value of first parameter is not in the range of 1 to 13")
except ValueError:
print ("The value of second parameter is not one of the strings in the set {'s','h','c','d'}")
print(c1)
我知道可能是因为我有相同的
TypeError
和ValueError
。因此,Python无法区分我点击的第二个TypeError
,c1=Card(13,13)
与第一个TypeError
不同。因此,当我有c1=Card(13,13)
时,我只得到一条信息,即“第一个参数不是整数”
,您试图在完全错误的位置区分错误源。当错误从卡中消失时,无法知道抛出的原因,例如类型错误
。对于每个错误类别(TypeError
,ValueError
)只会触发除
之外的第一个:
try:
...
except TypeError:
# all TypeErrors end up here
except TypeError:
# this is *never* reached
except ValueError:
# all ValueErrors end up here
except ValueError:
# this is *never* reached
相反,您应该在卡中提供具体的错误消息。当您实际引发错误并且已经知道原因时:
if not isinstance(rank, int): # better than comparing to type
raise TypeError("The first parameter is not an integer")
然后,您可以更简单地处理它们:
try:
c1 = Card(19,13)
except (TypeError, ValueError) as err: # assign the error to the name 'err'
print(err) # whichever we catch, show the user the message
else:
print(c1) # only print the Card if there were no errors
如果您特别需要区分同一类的不同错误,可以显式检查消息:
except TypeError as err:
if err.args[0] == "The first parameter is not an integer":
# do whatever you need to
或者创建您自己的、更具体的异常
子类,这样您就可以拥有单独的异常
块:
class FirstParamNotIntError(Exception):
pass
(这只是一个例子,它们在您的特定案例中太具体了)
可能值得一读。我只想补充一点,比较异常消息通常只能作为最后的手段,尤其是当引发异常的代码不是您的代码时。异常消息确实会被更改,因此它会创建非常脆弱的代码。当然不要害怕创建自己的异常(子)类,如果它允许您捕获有关错误的更好信息。谢谢您,Jonrsharpe。非常有用。我遵循了您的建议和您在上面发布的链接,但是如果我输入c1=Card(12,'h'),我最后的代码无法为我提供正确的输出,因为它仍然提供ValueError。对于我在诉讼中的第二个错误,我写了if suit!=self.suit:raise ValueError(“第二个参数的值不是集合中的一个……对于代码末尾的try/except,我使用c1=卡(12,'h')编写了相同的try。except(TypeError,ValueError)作为err:print(err)else:print(c1)。但是,它仍然给了我ValueError。我的代码有什么问题?@WuChu为什么你希望suit!=self.suit
工作?!你刚刚检查的东西怎么可能是字符串等于字典?也许你应该看看。另外,对类属性和实例属性使用相同的名称是一个糟糕的举动。@jornsharpe好的,我可以将suit!=self.suit改成suit!='d'或'h'或'c'或's'或suit不在self.suit中。但是,对于类属性和实例属性的相同名称来说,什么是坏动作?这与为什么我输入c1=卡(13,'d')时没有得到正确的输出有关吗?这仍然是不正确的-你阅读了我刚才链接的问题吗?另外,我的意思是你正在使用例如rank
作为有效列组列表和当前实例的列组。谢谢你,Jonrsharpe。非常有用。我遵循了你的建议和你上面发布的链接,但是如果我输入,我最后的代码不能给我正确的输出t c1=Card(12,'h'),因为它仍然给出ValueError。对于suit中的第二个ValueError,我写了if suit!=self.suit:raise ValueError(“第二个参数的值不是集合中的一个…”,对于代码末尾的try/except,我用c1=Card(12,'h')写了相同的try。除了(TypeError,ValueError)作为err:print(err)其他:打印(c1)。但是,它仍然给我ValueError。我的代码有什么问题?