[Python] 碎片 - 类
例: Fraction 类
重写 __init__ 方法
要创建一个 Fraction
对象,需要提供分子和分母两部分数据。在 Python 中,构造方法总是命名为 __init__
(即在 init 的前后分别有两个下划线)
Fraction
类及其构造方法:
class Fraction:
def __init__(self, top, bottom):
self.num = top
self.den = bottom
注意:形式参数列表包含 3 项。 self 是一个总是指向对象本身的特殊参数,它必须是第一个形式参数。
构造方法中的
self.num
定义了Fraction
对象有一个叫作num
的内部数据对象作为其状态的一部分。同理,self.den
定义了分母。这两个实际参数的值在初始时赋给了状态,使得新创建的Fraction
对象能够知道其初始值。
要创建 Fraction
类的实例,必须调用构造方法。使用类名并且传入状态的实际值就能完成调用(注意,不要直接调用 __init__
)。
myfraction = Fraction(3,5)
以上代码创建了一个对象,名为 myfraction,值为 3/5。
打印 Fraction 对象:
>>> myf = Fraction(3,5)
>>> print(myf)
<__main__.Fraction instance at 0x409b1acc>
Fraction
对象 myf
并不知道如何响应打印请求。 print
函数要求对象将自己转换成一个可以被写到输出端的字符串。 myf
唯一能做的就是显示存储在变量中的实际引用(地址本身)。这不是我们想要的结果。
重写 __str__ 方法
解决方法一:show 方法
def show(self):
print(self.num, "/", self.den)
解决方法二:将对象转换成字符串(__str__
方法)
def __str__(self):
return str(self.num) + "/" + str(self.den)
定义一个名为
__str__
的方法,重写默认实现,或者说重新定义该方法的行为。
一旦要求 Fraction
对象转换成字符串,就会返回结果。
>>> myf = Fraction(3,5)
>>> print(myf)
3/5
>>> print("I ate", myf, "of the pizza")
I ate 3/5 of the pizza
>>> myf.__str__()
'3/5'
>>> str(myf)
'3/5'
>>>
重写 __add__ 方法
__add__
方法需要两个参数。第一个仍然是 self,第二个代表了表达式中的另一个操作数。
f1.__add__(f2)
以上代码会要求 Fraction
对象 f1
将 Fraction
对象 f2
加到自己的值上。可以将其写成标准表达式: f1 + f2
。
def __add__(self, otherfraction):
newnum = self.num * otherfraction.den + \
self.den * otherfraction.num
newden = self.den * otherfraction.den
return Fraction(newnum, newden)
两个分数需要有相同的分母才能相加,确保分母相同最简单的方法是使用两个分母的乘积作为分母。
>>> f1 = Fraction(1, 4)
>>> f2 = Fraction(1, 2)
>>> f3 = f1 + f2
>>> print(f3)
6/8
>>>
gcd 函数
虽然这一方法能够与我们预想的一样执行加法运算,但它并不是最简分数。为了保证结果总是最简分数,需要化简分数。我们需要寻找分子和分母的最大公因数(greatest commondivisor, GCD),然后将分子和分母分别除以最大公因数,最后的结果就是最简分数。
欧几里得算法:对于整数 m 和 n,如果 m 能被 n 整除,那么它们的最大公因数就是 n。然而,如果 m 不能被n 整除,那么结果是 n 与 m 除以 n 的余数的最大公因数。
def gcd(m,n):
while m%n != 0:
oldm = m
oldn = n
m = oldn
n = oldm%oldn
return n
注意:这种实现只有在分母为正的时候才有效。
改良版add方法:
def __add__(self, otherfraction):
newnum = self.num * otherfraction.den + \
self.den * otherfraction.num
newden = self.den * otherfraction.den
common = gcd(newnum, newden)
return Fraction(newnum//common, newden//common)
重写 __eq__ 方法
假设有两个 Fraction
对象, f1
和 f2
。只有在它们是同一个对象的引用时, f1 == f2
才为 True
,这被称为浅相等。
在 Fraction
类中,可以通过统一两个分数的分母并比较分子来实现 __eq__
方法。
def __eq__(self, other):
firstnum = self.num * other.den
secondnum = other.num * self.den
return firstnum == secondnum
注意:其他的关系运算符也可以被重写。例如,
__le__
方法提供判断小于等于的功能。
Fraction 类的完整实现:
class Fraction:
def __init__(self, top, bottom):
self.num = top
self.den = bottom
def __str__(self):
return str(self.num) + "/" + str(self.den)
def show(self):
print(self.num, "/", self.den)
def __add__(self, otherfraction):
newnum = self.num * otherfraction.den + \
self.den * otherfraction.num
newden = self.den * otherfraction.den
common = gcd(newnum, newden)
return Fraction(newnum//common, newden//common)
def __eq__(self, other):
firstnum = self.num * other.den
secondnum = other.num * self.den
return firstnum == secondnum
本作品采用 知识共享署名-相同方式共享 4.0 国际许可协议 进行许可。
评论已关闭