繁体   English   中英

代码在错误的 class 中寻找属性

[英]Code is looking for attributes in the wrong class

这段代码真的没有完成,但它已经到了那里。 我正在尝试将项目名称和价格的输入组织到列表中,但由于代码在项目 class 而不是收据 class 中查找 _purchases 属性而导致错误。 这是什么原因造成的?

import datetime

class Item:
    def __init__(self,_name="None",_price=0,_taxable="no"):
        self._name=_name
        self._price=_price
        self._taxable=_taxable
    def __str__(self):
        base="{:-<20}".format(self._name)+"{:->20}".format(self._price)
        return base
    def getPric(self):
        pass
    def getTax(self):
        pass

class Receipt:
    def __init__(self,_tax_rate=0,_purchases=""):
        self._tax_rate=_tax_rate
        self._purchases=_purchases
    def __str__(self):
        pass
    def additem(self):
        list=self._purchases.append(self)
        
#Main Program
if __name__=="__main__":
    loop="no"
    print("Welcome to Receipt Creator")
    while True:
        name=input("Enter Item name: ")
        price=float(input("Enter Item Price: "))
        taxable=input("Is the item taxable (yes/no): ")
        product=Item(name,price,taxable)
        print(product)
        print(Receipt.additem(product))
        print(list)
        loop=input("Add another item (yes/no): ")
        if loop=="yes":
            continue
        else:
            break
    print("----- Receipt",str(datetime.datetime.now()),"-----")
    print(list)

编辑:这是错误

Traceback (most recent call last):
  File "C:\Users\lucas\Desktop\main.py", line 35, in <module>
    print(Receipt.additem(product))
  File "C:\Users\lucas\Desktop\main.py", line 23, in additem
    list=self._purchases.append(self)
AttributeError: 'Item' object has no attribute '_purchases'

您对自己拥有的东西有一个清晰的认识,但执行力还有很大的改进空间。

让我们不要碰Item class,因为这不是造成麻烦的那个。 但是关于Receipt ,让我们创建一个purchases列表来保存购买,让我们定义一个方法( add_item )来填充该列表:

class Receipt:
    def __init__(self, tax_rate=0):
        self.tax_rate = tax_rate
        self.purchases = []

    def add_item(self, item):
        self.purchases.append(item)

现在,您肯定需要实例化该Receipt class (与您所做的相反),因此在您的主循环中您应该具有以下内容:

if __name__=="__main__":
    print("Welcome to Receipt Creator")
    rcpt = Receipt()
    while True:
        name = input("Enter Item name: ")
        price = float(input("Enter Item Price: "))
        taxable = input("Is the item taxable (yes/no): ")
        product = Item(name, price, taxable)
        print(product)
        rcpt.add_item(product)
        print(rcpt.purchases)
        loop = input("Add another item (yes/no): ")
        if loop == "yes":
            continue
        else:
            break
    print(rcpt.purchases)

现在,在您之前的代码中需要注意一些事项:

  • 除非您想让其他人知道某个属性只能在 class 的定义中使用,否则实际上不需要使用前导下划线来命名属性。
  • 您试图打印list 请记住, list是内置的 class,因此请尝试使用不同的名称命名您的属性(实际上,您可以使用尾随下划线。就像list_ )。 此外,您试图打印您在additem()方法中定义的list属性,而没有实例化Receipt class 并询问 class (类似于instance.list_ )。
  • 在您定义的Receipt class 的__init__方法中,您的_purchases的默认值为"" (一个空字符串),但该属性旨在成为一个列表。 (因为您试图在additem()方法之后使用append()方法),这根本没有意义。

@revliscano 有一个可以解决您的问题的答案。 我会把答案留给他。 我只是要解释为什么你得到了你得到的有点令人困惑的错误。

在项目 class 中寻找 _purchases 属性

在您的 class Receipt中,您有:

class Receipt:
    ...
    def additem(self):
        list=self._purchases.append(self)

后来用:


        product=Item(name,price,taxable)
        print(product)
        print(Receipt.additem(product))

因此,您在Receipt class 上调用additem() ,而不是在该 class 的实例上调用。 通常当你调用一个实例方法时,你调用它的实例是由 python 作为self传入的。 It did not have an instance since you called it on the class itself, and as a result under the hood python was passing the product in as the self variable because python was treating it like a call on a static class method though it was supposed to是一个实例方法(即没有clsself arg,只需将给定的 arg 传递给方法)。 因此,因为您像Receipt.additem(product)一样调用它,所以product作为self传递。

这意味着当它尝试执行self._purchases.append(self)时,就像它正在尝试执行product._purchases.append(product)一样,因此它试图在product上找到_purchases属性。 由于productItem class 的一个实例,这就是您获得令人困惑的错误消息的方式。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM