【问题标题】:How would I make a loop that creates instances in python 3?我将如何创建一个在 python 3 中创建实例的循环?
【发布时间】:2015-10-02 12:46:51
【问题描述】:

我看过像Creating instances in a loop 这样的问题,但我每次都需要创建具有不同值的新实例,而不是一堆实例的克隆。

下面,我为 Bill 类的实例编写了一个餐厅小费计算器(含税)。我写了一个类方法,当第一个实例的计算完成时创建一个新实例。

虽然如果我打开 .py 文件以继续添加新实例并调用所需的所有类方法,这会有效,但如果我以某种方式创建了一个循环,当我键入“yes”时会创建一个新实例,这将更加有用"在第二类方法的self.choice中。

我之前创建循环的尝试导致创建了未命名的实例。 “退货单(示例,示例,示例)”不适合我,因为我无法调用它的方法(我可能可以,但它会让人头疼并且不会是 pythonic。)我也不能将其附加到列表中。

persons = []

class Bill:
    def __init__(self, check, tax, tip):
        self.check = check
        self.tax = tax
        self.tip = tip

    def addPersons(self):
        self.choice = input("Do you want to calculate for another person?")
        if self.choice == "Yes" or self.choice == "yes":
            person2 = Bill(float(input("Check: ")), float(input("Tax: ")), float(input("Tip: ")))
            return person2
        else:
            pass

    def percent(self):
        self.tax = self.tax/100
        self.tip = self.tip/100

    def calculate(self):
        self.result_1 = self.check + (self.check * self.tax)
        self.result_final = self.result_1 + (self.result_1 * self.tip)
        self.difference = self.result_final - self.result_1
        self.advice = self.result_1, "is your check with tax added.", self.difference, "is how much tip you need to pay.", self.result_final, "is your total."
        return self.advice

a = Bill(float(input("Check: ")), float(input("Tax: ")), float(input("Tip: ")))
a.percent()
a.calculate()
print(a.advice)
persons.append(a)

b = a.addPersons()
b.percent()
b.calculate()
print(b.advice)
persons.append(b)

c = b.addPersons()
c.percent()
c.calculate()
print(c.advice)
persons.append(c)

感谢您的宝贵时间和帮助。 :)

【问题讨论】:

  • 我不清楚您要完成什么以排除循环。您能否更具体地说明您想要做什么以及您对循环的尝试做了什么?
  • 当然。 (我不排除循环,我想要一个循环。我只是想解释我自己的循环是如何失败的。)由于我需要动态数量的实例(与不同数量的朋友一起出去),我想“虽然每次前一个实例完成计算时,self.choice == 'yes'" 循环都会创建一个新实例。我只是没有足够的知识来制作一个工作循环。

标签: python oop loops python-3.x


【解决方案1】:

我会从类中重构addPersons() 方法,并执行如下所示的操作。请注意,我还让calculate() 自动调用percent(),这样就不必在外部完成。

这是一个更好的设计,因为它将与用户交互的责任转移到类本身之外(这并不是它真正关心的问题)。它还允许它用于不同的用户界面或以编程方式使用,例如来自数据库或其他容器中的数据。

class Bill:
    def __init__(self, check, tax, tip):
        self.check = check
        self.tax = tax
        self.tip = tip

    def percent(self):
        self.tax = self.tax/100
        self.tip = self.tip/100

    def calculate(self):
        self.percent()
        self.result_1 = self.check + (self.check * self.tax)
        self.result_final = self.result_1 + (self.result_1 * self.tip)
        self.difference = self.result_final - self.result_1
        self.advice = (self.result_1, "is your check with tax added.",
                       self.difference, "is how much tip you need to pay.",
                       self.result_final, "is your total.")
        return self.advice

bills = []
while True:
    choice = input("Do you want to calculate for another person?")
    if choice.lower().startswith("y"):
        break
    bill = Bill(float(input("Check: ")), float(input("Tax: ")),
                float(input("Tip: ")))
    bill.calculate()
    print(*bill.advice)
    bills.append(bill)

循环不会创建Bill 类的命名实例。相反,它将它们全部存储在一个名为bills 的列表中。如果您想将一个人的名字与每个人关联起来,您可以将他们放在一个按名字键入的字典中。

bills = {}
while True:
    choice = input("Do you want to calculate for another person?")
    if choice.lower().startswith("y"):
        break
    person_name = input("Enter the name of the person: ")
    if not person_name:
        continue  # ask about continuing again
    bill = Bill(float(input("Check: ")), float(input("Tax: ")),
                float(input("Tip: ")))
    bill.calculate()
    print("{}'s bill:".format(person_name))
    print(*bill.advice)
    bills[person_name] = bill

【讨论】:

  • 感谢您优化我的代码并提供此答案。然而,一个问题是,我将如何重命名每个实例以使它们不都是“账单”?当我在考虑制作循环的方法时,我认为这是最让我感到沮丧的事情。另外,在打印账单列表时有没有使用 str 的好方法? (抱歉修改了这么多)
  • 这是可能的,但您不希望以编程方式命名实例,因为您的其余代码将无法知道创建了哪些变量名称。最好将它们放在像list 这样的容器中,并将它们引用为bill[0]bill[1] 等。您可以将name 属性添加到其中包含人名的Bill 类的实例.然后你可以在需要时print(bill[i].name)。或者,您也可以将实例存储在由人名键入的字典中。我不确定您在打印账单列表时使用 str 是什么意思。
  • 如果有帮助,请考虑接受和/或投票赞成我的回答。谢谢。
  • 我建议使用choice.lower().startswith('y') 而不是choice.lower()[0] 来处理用户只按Enter 键而没有任何字符的情况。我还将输出解压到print(*bill.advice),以便更整齐地打印tuple。澄清一下bills[0] 之类的引用与a 之类的引用一样有效。
  • @TigerhawkT3:很好的建议。谢谢。
猜你喜欢
  • 2016-09-06
  • 1970-01-01
  • 2014-06-28
  • 1970-01-01
  • 2013-04-19
  • 2018-04-02
  • 1970-01-01
  • 2016-10-17
  • 1970-01-01
相关资源
最近更新 更多