-
Notifications
You must be signed in to change notification settings - Fork 0
FAQs for Lab 1
在 Python 中,raise
语句专门用于抛出异常(exception)。异常的意思是,程序遇到了设计者不愿意看到的情况,例如在 Rational
类初始化的时候分母为 0,就应该抛出一个 ZeroDevisionError
,以提醒调用者这里出现了除零异常。如果要捕获这个异常,可以使用 try
except
finally
语句,例如:
def raiseError():
raise NotImplementedError("This function shouldn't be called!")
if __name__ == "__main__":
try:
raiseError()
except NotImplementedError:
print("An exception flew by!")
finally:
print("This will always be printed")
关于异常和异常处理的更多信息,可以参考 Built-in Exceptions 。
运算符重载就是指,当我对一个类进行加减乘除等操作时,我要进行一些特殊处理。在 Python 的内置类型中可以看到这样的例子,整数加法返回整数,字符串加法返回连接后的字符串,显然,这个 +
符号带有一词多义的特性。当我们使用 a + b
时,事实上它调用了一个方法 __add__
,请看以下代码:
i = 3
i = i.__add__(4)
print(i)
这里的输出结果是 7,正是 3 + 4 运算的结果。这意味着,当我执行 i + 4
的求值时,其求值过程就是 i.__add__(4)
,这是运算符重载的基本原理。
重载(override)是指,当一个新的类继承自原先的类时,我们使用同名函数代替原先类中的同名函数。这样,在新的类调用这个函数时,它就不会调用其父类的同名函数。因此,只需要重载 __add__
函数,即可实现自定义类的加法。关于各个运算符对应的方法,可以参考 Operators 。
在后面的要求中,我们要求实现判断语句。在实现 ==
的过程中,可能会发现,调用 ==
并不会报 NotImplementedError
。原因是任何一个类都继承了一个叫做 type
的基类,其中自带有 __eq__
方法,这个方法对于任何两个不同的实例都会返回 False
。而在原始版本的 Number
类中事实上已经重载了 __eq__
,为了降低难度删去但未删去相关的要求,于是造成了一些混乱。解决的方法就是,在 Rational
类中自己定义 __eq__
方法,也可以选择在 Number
类中加上对应的 NotImplementedError
。
当调用 print
函数时,会调用 __str__
方法,并输出返回值字符串。这是对 __str__
方法的最简单理解。因此,如果对于分母为 1 直接以整数方式输出分子,可以修改原有的 __repr__
和 __str__
方法。
这部分确实超出了我们所提供的内容的范畴。有兴趣的同学可以参考 Data Model 中对类生成的描述,重载 __new__
方法来尝试实现。例如,我们以 NaN
为例,在 Rational
类中应该如此定义:
class Rational:
...
def __init__(self, p, q):
if p == 0:
self.q = 1
self._simplify()
def __new__(cls, p, q):
obj = object.__new__(cls)
obj.p = p
obj.q = q
if p == 0 and q == 0:
return NaN()
return obj
...
这样,当 p
和 q
都为 0 时,构造 Rational(0, 0)
将返回一个 NaN
类的实例。
Embedded Artificial Intelligence @ ZJU