Python 为_init中的非int参数引发异常__

Python 为_init中的非int参数引发异常__,python,exception,Python,Exception,我想实现类分数,这样当我传递非整数时,就会引发异常,并且不会创建对象。以下代码引发了一个异常,但在中可以创建一个奇怪的分数“hello,world”/0 问题是,如何优雅地捕捉非整数输入和0分母 更新 完全忘记了我需要提出一个例外,而不仅仅是makeexcept子句。下面是代码现在的样子 class Fraction: def __init__(self, num, den): if not (isinstance(num, int) and isinstance(den

我想实现类分数,这样当我传递非整数时,就会引发异常,并且不会创建对象。以下代码引发了一个异常,但在中可以创建一个奇怪的分数“hello,world”/0

问题是,如何优雅地捕捉非整数输入和0分母

更新 完全忘记了我需要提出一个例外,而不仅仅是makeexcept子句。下面是代码现在的样子

class Fraction:
    def __init__(self, num, den):
        if not (isinstance(num, int) and isinstance(den, int)):
            raise TypeError('Got non-int argument')
        if den == 0:
            raise ValueError('Got 0 denominator')
        self.num = num
        self.den = den 
在except块中,只引发原始异常。 要检查零分母,只需执行以下操作:

if den == 0:
    raise ValueError("boom")

可以使用factory方法创建对象:

class Fraction:
    def __init__(self, num, den):
        self.num = num
        self.den = den

def new_fraction(num, den):
    try:
        num = int(num)
        den = int(den)
        return Fraction(num, int)
    except ValueError:
        print('Passed argument not convertible to int')
然后,当需要新分数时,调用factory方法:

my_fraction = new_fraction(1,5)
然后需要测试我的分数是否为零:

if my_fraction is not None:
    # Do stuff
else:
    # my_fraction is not an instance of Fraction, so do something else

如果要打印或记录错误消息并引发异常,只需将其添加到现有的except套件中即可—它将引发最新的异常。使用描述符拒绝零分母。非零改编自


对于后人来说,我的第一个解决方案是使用assert拒绝分母的零值,因此@PM2Ring给出了注释。我和自己讨论过如何使用它。它的docs state:Assert语句是将调试断言插入到程序中的一种方便方法,下面是:断言*不*用于测试可能由于错误的用户输入而发生的失败情况—所以我的错误。描述符就是要走的路。但肯定很方便

在代码的某个地方,您将调用

my_fraction = Fraction(num, den)
为什么不把它改成:

if type(num) is int and type(den) is int:
  my_fraction = Fraction(num, den)
else:
  print('Passed argument not convertible to int')

这样就永远不会创建对象。如果需要,您还可以添加异常。

发现问题后,您希望发生什么?该对象应该仍然被创建,还是被中止?为什么不添加像if typenum这样的检查呢=int:?我认为在尝试实例化分数之前,最好检查num和den。这样的设计似乎更好,因为您可以更好地控制要做的事情。@metatoaster如果引发异常,我希望该对象被中止。@Sweeney Todd我知道,但tasks说要用异常来做,我很好奇用这种方式来尝试。这是一种练习,所以重点是自己实现类分数。没问题,您现在可以在问题中添加一个错误。请注意,您通常不希望使用isinstancenum,int。您希望检查它的行为是否类似于int,而不是它是否是int-类似于int的自定义类不应引发值错误。请不要这样使用assert。assert应该用于捕获代码中的逻辑错误,而不是捕获错误数据。相反,您应该做一些类似于raise VALUERROR“零分母”的事情。感谢您摆脱了不恰当的assert语句。OTOH,我认为你的非零是过火了。我看不出den=NonZero1有什么意义:它创建了一个类属性,而不是代码其余部分没有使用的实例属性。顺便说一句,你应该看看Basil的后续问题:。@PM2Ring-描述符的额外复杂性是我选择断言的一个原因,尽管这被误导了。。。在本例中,类属性den与self.den=den一起使用。这个描述符的想法一开始对我来说有点奇怪,但我发现了很多类似的实现。
my_fraction = Fraction(num, den)
if type(num) is int and type(den) is int:
  my_fraction = Fraction(num, den)
else:
  print('Passed argument not convertible to int')