【问题标题】:Keep on getting an AttributeError and not sure why [closed]继续得到一个 AttributeError 并且不知道为什么[关闭]
【发布时间】:2019-11-27 21:40:06
【问题描述】:
def gcd(n, d):
        if n==0 or d==0:
            return 1
        while(n != d):
            if(n > d):
                n = n - d
            else:
                d = d - n
        return n

class Fraction:
    def __init__(self, n, d):
        self.num = int(n / gcd(abs(n), abs(d)))
        self.denom = int(d / gcd(abs(n), abs(d)))
        if self.denom < 0:
            self.denom = abs(self.denom)
            self.num = -1 * self.num
        elif self.denom == 0:
            raise ZeroDivisionError
    def __str__(self):
        if type(self) is tuple:
            if self[1] < 0:
                return '%s/%s' %(self[0], -1*self[1])
            else:
                return '%s/%s' %(self[0], self[1])
        elif self.denom == 1:
            return str(self.num)
        else:
            return '%s/%s' %(self.num, self.denom)

    def __add__(self, other):
        return self.num*other.denom + self.denom*other.num, self.denom*other.denom

    def __sub__(self, other):
        return self.num*other.denom - self.denom*other.num, self.denom*other.denom

    def __mul__(self, other):
        return self.num*other.num, self.denom*other.denom

    def __div__(self, other):
        return self.num*other.denom, self.denom*other.num

    def __eq__(self, other):
        if self.num == other.num and self.denom == other.denom:
            return "Equal"
        else:
            return "Not Equal"


f1 = Fraction(2, 4)
f2 = Fraction(4, 20)
add = Fraction.__add__(f1, f2)
sub = Fraction.__sub__(f1, f2)
eq = Fraction.__eq__(f1, f2)
mul = Fraction.__mul__(f1, f2)
div = Fraction.__div__(f1, f2)
print("Fraction one: "+str(Fraction.__str__(f1))+"\n"+"Second Fraction: "+str(Fraction.__str__(f2))+"\n"+"Add: "+str(Fraction.__str__(add))+"\n"+"Subtract: "+str(Fraction.__str__(sub))+"\n"+"Multiply: "+str(Fraction.__str__(mul))+"\n"+"Divide: "+str(Fraction.__str__(div))+Fraction.__str__(eq))

所以我的作业要求我创建一个分数函数,但我的代码不断收到以下错误,我不知道为什么:

Traceback (most recent call last):
  File "G:\Workshops\Week9.py", line 57, in <module>
    print("Fraction one: "+str(Fraction.__str__(f1))+"\n"+"Second Fraction: "+str(Fraction.__str__(f2))+"\n"+"Add: "+str(Fraction.__str__(add))+"\n"+"Subtract: "+str(Fraction.__str__(sub))+"\n"+"Multiply: "+str(Fraction.__str__(mul))+"\n"+"Divide: "+str(Fraction.__str__(div))+Fraction.__str__(eq))
  File "G:\Workshops\Week9.py", line 26, in __str__
    elif self.denom == 1:
AttributeError: 'str' object has no attribute 'denom'

【问题讨论】:

  • 您从__eq__ 返回一个字符串(这不好),然后在您编写Fraction.__str__(eq) 时将字符串eq 传递给str。为什么要手动调用__ 方法,为什么要从__eq__ 返回字符串?这两个问题都导致了这个错误(尽管手动调用魔法方法是更大的问题)。
  • 我是编程新手,但有人告诉我显示输出,他们特别希望我使用“__ x __”来定义方法
  • @NotHamzah 是的,您应该这样定义它们,但永远不要这样明确地称呼它们(在非常特殊和特殊的情况下)。因此,您应该使用f1 + f2 来代替`Fraction.__add__(f1, f2)` ...这就是重点。另外,你到底为什么要在__str__ 实现中检查if type(self) is tuple:?为什么self 会成为tuple???
  • @juanpa.arrivillaga 老实说,直到现在你才知道self 是什么。我从来没有试过。这段代码弄乱了我的脑袋好几分钟。我以前从未见过self 不是封闭类的类型。
  • @Carcigenicate 是的,我的意思是,SomeClass.func 将始终返回只是一个普通函数,这就是方法。 self 只是一个普通参数,如果通过描述符协议通过实例调用它只是绑定到实例,因为函数对象是描述符!您可以在函数外部定义def foo(self): ...,然后将其分配给SomeClass.foo = foo 类,现在它是一个适用于实例的方法,而且self 只是一个约定而已之所以重要,是因为它是第一个位置参数

标签: python python-3.x fractions


【解决方案1】:

他们希望您使用__定义方法,但这不是您使用方法的方式。

__add__ 例如是+。而不是写

add = Fraction.__add__(f1, f2)

随便写

add = f1 + f2

所有其他数学运算符以及__str__(这是str 内置使用的)也是如此。

您的主要问题是 eq 是一个字符串*,并且您在编写时将它传递给您的 __str__ 方法

Fraction.__str__(eq)

这意味着您的__str__ 内部的self字符串,而不是Fraction,这意味着self.denom 是,如错误所示,试图从字符串self 中获取denom 属性。

既然你有eq作为一个字符串,只需改变

Fraction.__str__(eq)

只是

eq

*实际上,__eq__ 不应该返回字符串。这不是不允许的,但它很奇怪并且使__eq__ 不是很有用。只要有

def __eq__(self, other):
    return self.num == other.num and self.denom == other.denom

然后将上面提到的修复更改为

str(eq)

【讨论】:

  • 谢谢,它现在可以工作了,我也设法将元组答案变成了我需要的形式。
猜你喜欢
  • 2021-12-25
  • 1970-01-01
  • 1970-01-01
  • 2013-06-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多