Python子类化

3

我有一个处理分数的类(例如(1,2),(3,4)等):

class Fraction(object):

    def __init__(self, num=0, denom=1):
        ''' Creates a new Fraction with numberator num and denominator denom'''
        self.numerator = num
        if denom != 0:
            self.denominator = denom
        else: 
            raise ZeroDivisionError
    def __str__(self):
        '''Returns the string numerator/denominator '''
        return "{0}/{1}".format(self.numerator, self.denominator)
    def __repr__(self):
        """blah"""
        return Fraction(self.numerator, self.denominator)

我希望创建一个子类Mixed number,它可以接受整数和分数(例如2个Fraction(1,2),3个Fraction(3,4)等)。然而,我不确定如何实现这一点。如果有任何帮助,请告诉我。

class MixedNumber(Fraction):

4
我认为让 MixedNumber 继承 Fraction 没有意义。将 Fraction 合成到 MixedNumber 类中会更加合理。 - Hunter McMillen
我同意@HunterMcMillen的观点,但是仅供参考,您在帖子末尾使用的语法在Python中是完全正确的继承方式。也许我没有理解您的问题或困惑所在; 您能否澄清一下? - jpmc26
1
子类继承意味着一种“是一个”的关系。因此,MixedNumber 似乎不适合从 Fraction 继承。 - zhangyangyu
2个回答

5

当考虑使用提供的Fraction类来实现MixedNumber类时,有两种方法立即出现在脑海中。一种方法是像@HunterMcMillen建议的那样,使用组合,即利用不同的对象分别表示整数和分数部分。这使您可以在类内访问每个对象的专门方法,如果您构建的组件具有各自封装的不同行为,则这非常方便。

class MixedNumber(object):
   def __init__(self, whole_number, fraction):
        self.whole_number = whole_number
        self.fraction = fraction

   def __str__(self):
        if self.fraction.numerator == 0:
            return str(self.whole_number)
        elif self.whole_number == 0:
            return str(self.fraction)
        else:
            return '{} {}'.format(self.whole_number,self.fraction)

   def __repr__(self):
        return 'MixedNumber({},{!r})'.format(self.whole_number,self.fraction)

另一种可能性是继承,如果你的Fraction类支持不恰当的分数,则可以使用子类来适当地处理初始化和混合数字格式的字符串呈现,如下所示:
class MixedNumber(Fraction):
    def __init__(self, whole_number, fraction):     
        num = whole_number * fraction.denominator + fraction.numerator
        super(MixedNumber,self).__init__(num,  fraction.denominator)

    def __str__(self):
        # assume positive fractions for demonstration only
        q, r = divmod(self.numerator,self.denominator)
        if r == 0:
            return str(q)
        elif q == 0:
            return super(MixedNumber,self).__str__() 
        else:
            return '{} {}/{}'.format(q,r,self.denominator)

    def __repr__(self):
        q, r = divmod(self.numerator, self.denominator)
        return 'MixedNumber({},Fraction({},{}))'.format(q,r,self.denominator)

你的Fraction.__repr__方法应该返回一个字符串,当传递给eval时,应该可以实例化与源对象相等的内容,即eval(frac) == frac。有关__str____eval__之间区别的更多细节,请参见此堆栈溢出问题

0

我最近完成了编写继承自标准库 Fraction 类的类 Mixed。它可能是使用父类现有功能的好指南。源代码在 这里。它接受任何库 Fraction 类接受的输入,以及混合数的字符串表示,例如 Mixed('3 4/5') 或有理数 whole_number/numerator/denominator 设置,如 Mixed(3,4,5)。所有 Fraction 的功能都得到了保留。 __str____repr__ 分别产生 3 4/5Mixed(3,4,5)。它使得转换为 float 或标准的 Fraction 就像 float(m)Fraction(m) 一样容易。干杯


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接