You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python类实现分数加法时GCD调用引发NameError问题求助

问题原因分析

你遇到的NameError本质是方法作用域错误:

  • 你把gcd和__add__定义在了Fraction类的外部,这两个函数并没有成为类的成员方法。
  • 当__add__里尝试调用gcd(new_num, new_den)时,Python会在当前全局作用域查找这个函数,但你的gcd定义带了self参数,它是一个不符合规范的全局函数,调用时也没传入self参数,自然会报错。
  • 你后来修改的gcd变体写法,依然是定义在类外,这里的self只是一个普通参数名,和类实例毫无关系,根本起不到作用。
解决方法

下面提供两种可行的修复方案:

方案1:将gcd和__add__转为类的实例方法

把这两个方法缩进,放到Fraction类的内部,让它们成为类的成员方法,调用时通过self访问gcd:

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

    def show(self):
        print(f'{self.num}/{self.den}')

    def __str__(self):
        return f'{self.num}/{self.den}'

    # 作为类的实例方法实现GCD
    def gcd(self, m, n):
        while m % n != 0:
            m, n = n, m % n
        return n

    # 把__add__放到类内部,作为重载的加法运算符
    def __add__(self, other_fraction):
        new_num = self.num * other_fraction.den + self.den * other_fraction.num
        new_den = self.den * other_fraction.den
        common = self.gcd(new_num, new_den)  # 通过self调用类内的gcd方法
        return Fraction(new_num // common, new_den // common)

# 测试代码
f1 = Fraction(1, 4)
f2 = Fraction(1, 2)
f3 = f1 + f2
print(f3)  # 输出 3/4,符合预期

方案2:使用Python内置的math.gcd函数

既然GCD是通用的数学计算,没必要自己实现,直接用标准库的math.gcd更可靠(支持Python 3.5及以上版本):

import math

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

    def show(self):
        print(f'{self.num}/{self.den}')

    def __str__(self):
        return f'{self.num}/{self.den}'

    def __add__(self, other_fraction):
        new_num = self.num * other_fraction.den + self.den * other_fraction.num
        new_den = self.den * other_fraction.den
        # 使用内置gcd,注意取绝对值(因为gcd返回非负数)
        common = math.gcd(abs(new_num), abs(new_den))
        # 确保负号只出现在分子上
        sign = -1 if (new_num < 0) ^ (new_den < 0) else 1
        return Fraction(sign * (abs(new_num) // common), abs(new_den) // common)

# 测试
f1 = Fraction(1, 4)
f2 = Fraction(1, 2)
f3 = f1 + f2
print(f3)  # 输出 3/4
额外提示
  • 运算符重载方法(比如__add__)必须定义在类内部,这样Python才能识别它是类的运算符重载逻辑。
  • 如果想让gcd不依赖类实例,可以把它定义为静态方法(用@staticmethod装饰器),这样就不需要self参数了:
    class Fraction:
        # ...其他方法...
        @staticmethod
        def gcd(m, n):
            while m % n != 0:
                m, n = n, m % n
            return n
    
        def __add__(self, other_fraction):
            # ...计算new_num和new_den...
            common = Fraction.gcd(new_num, new_den)  # 通过类名调用静态方法
            return Fraction(new_num//common, new_den//common)
    

内容的提问来源于stack exchange,提问作者Simba

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.29 10:09:07