如何处理 python 对象创建期间的错误
How to handle error during python object creation
我正在尝试写一个 class 来帮助我输出带分数。
这段代码对我来说工作正常
class mixed_fraction():
from fractions import Fraction
'''Returns mixed fractions in tuple format
(whole_part, numerator, denominator)
'''
def __init__(self, numerator = 0, denominator = 1):
self.numerator = numerator
self.denominator = denominator
def mixed(self):
if self.denominator == 0:
return 'Denominator cannot be Zero'
quotient = int(self.numerator/self.denominator)
remain = self.numerator - (self.denominator * quotient)
frac = Fraction(remain, self.denominator)
return (quotient, frac.numerator, frac.denominator)
示例输入
print(mixed_fraction(3, 2).mixed())
print(mixed_fraction(1, 5).mixed())
print(mixed_fraction(1, 0).mixed())
print(mixed_fraction().mixed())
print(mixed_fraction(7, 2).mixed())
print(mixed_fraction(769, 17).mixed())
print(mixed_fraction(384, 256).mixed())
产出
(1, 1, 2)
(0, 1, 5)
Denominator cannot be Zero
(0, 0, 1)
(3, 1, 2)
(45, 4, 17)
(1, 1, 2)
但我希望能够在创建对象时指出零错误,因为首先创建一个零除数的分数是没有意义的。所以我需要帮助及时发现错误。
class mixed_fraction():
from fractions import Fraction
'''Returns mixed fractions in tuple format
(whole_part, numerator, denominator)
'''
def __init__(self, numerator = 0, denominator = 1):
self.numerator = numerator
self.denominator = denominator
if denominator == 0:
return 'Denominator cannot be Zero'
def mixed(self):
quotient = int(self.numerator/self.denominator)
remain = self.numerator - (self.denominator * quotient)
frac = Fraction(remain, self.denominator)
return (quotient, frac.numerator, frac.denominator)
问题是 __init__
必须 return None
。所以我不知道如何解决这个问题
好吧,如果用户提供的值对您给定的对象没有意义,提出ValueError
而不是继续创作:
def __init__(self, numerator = 0, denominator = 1):
self.numerator = numerator
if self.denominator == 0:
raise ValueError("argument 'denominator' cannot be zero")
self.denominator = denominator
这是处理此类案件的标准方式。
顺便说一句,两件小事:
- 为您的 class 名称使用驼峰式大小写,即使用
MixedFraction
而不是 mixed_fraction
。 (除此之外:不需要括号)
- 不要在 class 主体中导入,在模块范围外导入。
- 如果您计划在期望您的对象表现得像
Fraction
的区域中使用它,请考虑从 Fraction
继承。
当您想在 Python 中生成错误时,您没有 return 值:您会引发错误。
在这种情况下,最合适的是 ZeroDivisionError:
def __init__(self, numerator = 0, denominator = 1):
self.numerator = numerator
self.denominator = denominator
if denominator == 0:
raise ZeroDivisionError('Denominator cannot be Zero!')
ZeroDivisionError 本身是 "ArithmeticError" 的特化 - 但您可以通过子 class 进一步自定义错误:
class ZeroDenominatorError(ZeroDivisionError):
pass
它的主要优点是程序流程可以层层下降
没有使用 try
...except
块正确处理错误的代码 - 直到你捕获它的地方 - 否则你必须在所有代码中放置一个 if
语句实例化 class 以检查 return 值类型的地方。
所以 - 这是正确的处理方式。现在,根据设计,可能希望 class 的实例化失败并且 return 另一个值("None" 比错误消息更好 - 有错误,只是提出一个例外)。在那种情况下,您应该编写 __new__
方法而不是 __init__
。与 __init__
不同,它必须 return 新创建的实例。 (它还必须通过正确调用 superclass 的 __new__
方法来 创建 那个新实例):
from fractions import Fraction
class MixedFraction(Fraction):
def __new__(cls, numerator=0, denominator=1):
if not denominator:
return None
instance = super().__new__(cls, numerator, denominator)
return instance
def mixed(self):
quotient = self.numerator // self.denominator
remain = self.numerator - (self.denominator * quotient)
return (quotient, remain, self.denominator)
至于 Hilliad 在他的回答中的建议,这直接继承自 "Fraction" - 这意味着它可以在任何使用 Fraction 的地方使用,但它有额外的 "mixed" 方法。请注意,如果您无论如何都在操作分子和分母参数,那么从 Fraction 继承将需要您编写 __new__
而不是 __init__
:它们是在实例化时在对象中设置的,在 native (C
) 代码,无法进一步更改。
我正在尝试写一个 class 来帮助我输出带分数。
这段代码对我来说工作正常
class mixed_fraction():
from fractions import Fraction
'''Returns mixed fractions in tuple format
(whole_part, numerator, denominator)
'''
def __init__(self, numerator = 0, denominator = 1):
self.numerator = numerator
self.denominator = denominator
def mixed(self):
if self.denominator == 0:
return 'Denominator cannot be Zero'
quotient = int(self.numerator/self.denominator)
remain = self.numerator - (self.denominator * quotient)
frac = Fraction(remain, self.denominator)
return (quotient, frac.numerator, frac.denominator)
示例输入
print(mixed_fraction(3, 2).mixed())
print(mixed_fraction(1, 5).mixed())
print(mixed_fraction(1, 0).mixed())
print(mixed_fraction().mixed())
print(mixed_fraction(7, 2).mixed())
print(mixed_fraction(769, 17).mixed())
print(mixed_fraction(384, 256).mixed())
产出
(1, 1, 2)
(0, 1, 5)
Denominator cannot be Zero
(0, 0, 1)
(3, 1, 2)
(45, 4, 17)
(1, 1, 2)
但我希望能够在创建对象时指出零错误,因为首先创建一个零除数的分数是没有意义的。所以我需要帮助及时发现错误。
class mixed_fraction():
from fractions import Fraction
'''Returns mixed fractions in tuple format
(whole_part, numerator, denominator)
'''
def __init__(self, numerator = 0, denominator = 1):
self.numerator = numerator
self.denominator = denominator
if denominator == 0:
return 'Denominator cannot be Zero'
def mixed(self):
quotient = int(self.numerator/self.denominator)
remain = self.numerator - (self.denominator * quotient)
frac = Fraction(remain, self.denominator)
return (quotient, frac.numerator, frac.denominator)
问题是 __init__
必须 return None
。所以我不知道如何解决这个问题
好吧,如果用户提供的值对您给定的对象没有意义,提出ValueError
而不是继续创作:
def __init__(self, numerator = 0, denominator = 1):
self.numerator = numerator
if self.denominator == 0:
raise ValueError("argument 'denominator' cannot be zero")
self.denominator = denominator
这是处理此类案件的标准方式。
顺便说一句,两件小事:
- 为您的 class 名称使用驼峰式大小写,即使用
MixedFraction
而不是mixed_fraction
。 (除此之外:不需要括号) - 不要在 class 主体中导入,在模块范围外导入。
- 如果您计划在期望您的对象表现得像
Fraction
的区域中使用它,请考虑从Fraction
继承。
当您想在 Python 中生成错误时,您没有 return 值:您会引发错误。
在这种情况下,最合适的是 ZeroDivisionError:
def __init__(self, numerator = 0, denominator = 1):
self.numerator = numerator
self.denominator = denominator
if denominator == 0:
raise ZeroDivisionError('Denominator cannot be Zero!')
ZeroDivisionError 本身是 "ArithmeticError" 的特化 - 但您可以通过子 class 进一步自定义错误:
class ZeroDenominatorError(ZeroDivisionError):
pass
它的主要优点是程序流程可以层层下降
没有使用 try
...except
块正确处理错误的代码 - 直到你捕获它的地方 - 否则你必须在所有代码中放置一个 if
语句实例化 class 以检查 return 值类型的地方。
所以 - 这是正确的处理方式。现在,根据设计,可能希望 class 的实例化失败并且 return 另一个值("None" 比错误消息更好 - 有错误,只是提出一个例外)。在那种情况下,您应该编写 __new__
方法而不是 __init__
。与 __init__
不同,它必须 return 新创建的实例。 (它还必须通过正确调用 superclass 的 __new__
方法来 创建 那个新实例):
from fractions import Fraction
class MixedFraction(Fraction):
def __new__(cls, numerator=0, denominator=1):
if not denominator:
return None
instance = super().__new__(cls, numerator, denominator)
return instance
def mixed(self):
quotient = self.numerator // self.denominator
remain = self.numerator - (self.denominator * quotient)
return (quotient, remain, self.denominator)
至于 Hilliad 在他的回答中的建议,这直接继承自 "Fraction" - 这意味着它可以在任何使用 Fraction 的地方使用,但它有额外的 "mixed" 方法。请注意,如果您无论如何都在操作分子和分母参数,那么从 Fraction 继承将需要您编写 __new__
而不是 __init__
:它们是在实例化时在对象中设置的,在 native (C
) 代码,无法进一步更改。