如何将来自不同函数的两个局部变量加在一起?

How can I add together two local variables from different functions?

我正在尝试编写一个程序来计算制作蛋糕所需的某些成分的数量,然后将这些数量加在一起计算出每种成分总共需要多少。

chocCupcake = int(input("How many chocolate cupcakes would you like to make? "))
lemonDrizzle = int(input("How many lemon drizzle cakes would you like to make? "))


def chocolate_cupcake():
    plainFlour = 12
    sugar = 14
    unsaltButter = 4
    freeRangeEgg = 0.1

    totalFlour = float(plainFlour * chocCupcake)
    totalSugar = float(sugar * chocCupcake)
    totalButter = float(unsaltButter * chocCupcake)
    totalEggs = float(freeRangeEgg * chocCupcake)

    print("""You will need:
"""+str(totalFlour)+""" grams of plain flour
"""+str(totalSugar)+""" grams of sugar
"""+str(totalButter)+""" grams of unsalted butter
"""+str(totalEggs)+" free range eggs ")

chocolate_cupcake()



def lemon_drizzle():
    plainFlour = 240
    sugar = 300
    unsaltButter = 80
    freeRangeEgg = 4.5

    totalFlour = float(plainFlour * lemonDrizzle)
    totalSugar = float(sugar * lemonDrizzle)
    totalButter = float(unsaltButter * lemonDrizzle)
    totalEggs = float(freeRangeEgg * lemonDrizzle)

    print("""You will need:
"""+str(totalFlour)+""" grams of plain flour
"""+str(totalSugar)+""" grams of sugar
"""+str(totalButter)+""" grams of unsalted butter
"""+str(totalEggs)+" free range eggs ")

lemon_drizzle()

所以我需要将两个函数的总面粉加在一起,以及总糖等。

有很多不同的方法可以做到这一点,因为它主要是一个重构问题。在我看来,最简单的方法是 return 这些成分作为每个函数的结果,如下所示:

def chocolate_cupcake():
    ...
    return [totalFlour, totalSugar, totalButter, totalEggs]

然后在调用每个函数时存储此信息

chocolate_ingredients = chocolate_cupcake()
lemon_drizzle_ingredients = lemon_drizzle()

然后你可以把它们加起来

print "Total Flour: " + (chocolate_ingredients[0] + lemon_drizzle_ingredients[0])
...etc

只是要补充一点,虽然这种方法需要更改现有代码最少,但绝对不是最好的方法。这不是最容易理解的。一个例子是为什么食谱方法会 return 随机顺序的成分列表。

您现在编写代码的方式 - 不可能这样做。局部变量是局部的。它们属于函数,不存在于函数之外。

您应该以不同的方式处理问题。您可以将它们存储在诸如地图之类的数据结构中,而不是将成分存储在函数内部(我只显示了 2 种成分):

ingredients = {"chocolate_cupcake": {"plainFlour": 12, "sugar": 14}, "lemon_drizzle": {"plainFlour": 240, "sugar": 300}}

然后获取一些蛋糕的配料是一个简单的字典理解问题:

choc_ingredients = {item: num_choc * required for item, required in ingredients["chocolate_cupcake"].items()}
lemon_ingredients = {item: num_lemon * required for item, required in ingredients["lemon_drizzle"].items()}

您可以使用 zip 将它们相加:

total_ingredients = {x[0][0]: x[0][1] + x[1][1] for x in zip(choc_ingredients.items(), lemon_ingredients.items())}

如果你是初学者,这里有很多新东西,但是这些方法对Python来说是非常基础的,所以你一定要学习它们。

您正在寻找 类 的面向对象设计(OOP - 面向对象编程)。字典或命名元组方法可能是最简单且最适合您项目的方法。

OOP 非常强大,值得了解。我将向您展示一些您可以使用 类 执行的更高级的操作。您可以使 类 使用 python 运算符 +、-、/、* 等 http://rafekettler.com/magicmethods.html

示例:

    import collections

class Ingredients(collections.OrderedDict):
    """List of ingredients with their amounts.

    You could customize this more to force each key to have a unit.
    You could also create your own Ingredient class that has a unit and
    force every value in this dictionary to be an Ingredient with the
    __setitem__ magic method.
    """
    def __init__(self, items):
        super().__init__(sorted(items)) # sort the items

        # Remove name
        if "name" in self:
            self.pop("name")

        # Force servings as the first item
        if "servings" not in self:
            self["servings"] = 1
        self.move_to_end("servings", last=False)
    # end Constructor

    def __str__(self):
        """Return the string representation."""
        return ", ".join((key+": "+str(self[key]) for key in self))
# end class Ingredients


class Cake(object):
    """Create a cake."""
    def __init__(self, number=1):
        super().__init__()

        self.name = "Cake"
        self.servings = 1

        self.init_ingredients()

        if number > 1:
            self *= number

    def init_ingredients(self):
        """Initialize ingredients."""
        self.flour = 240
        self.sugar = 300
    # end init_ingredients

    def ingredients(self):
        """Return a copy of the ingredients."""
        # self.__dict__ contains all of the users variables
        return Ingredients(self.__dict__.items())
    # end ingredients

    def update_ingredients(self, other):
        """Update the ingredients values from a dictionary."""
        self.__dict__.update(other)
    # end update_ingredients

    def show_ingredients(self):
        ingred = str(self).replace(", ", "\n")
        print(ingred)
    # end show_ingredients

    def __str__(self):
        return self.name +", "+ str(self.ingredients())
    # end __str__

    def __add__(self, other):
        """Add the total number of ingredients. Uses + operator (mycake + 2)."""
        if not isinstance(other, Cake):
            raise TypeError

        # Add ingredients
        ingredients = self.ingredients()
        otheri = other.ingredients()
        for key in otheri:
            try:
                ingredients[key] = ingredients[key] + otheri[key]
            except KeyError:
                ingredients[key] = otheri[key]                

        # Edit the name?
        ingredients["name"] = self.name
        if other.name not in self.name:
            ingredients["name"] = self.name + " & " + other.name

        new_cake = self.__class__()
        new_cake.update_ingredients(ingredients)
        return new_cake
    # end __add__

    def __iadd__(self, other):
        """Add and store."""
        ingredients = self + other
        self.update_ingredients(ingredients) 
        return self
    # end __iadd__

    def __imul__(self, other):
        """multiply and store. Uses * operator (mycake *= 2)."""
        ingredients = self.ingredients()
        for key in ingredients:
            ingredients[key] *= other
        self.update_ingredients(ingredients)
        return self
    # end __imul__

    def __mul__(self, other):
        """Copy and return the multiplied value. Uses * operator (mycake * 2)."""
        new_cake = self.__class__()
        new_cake.update_ingredients(self.ingredients())
        new_cake *= other
        return new_cake
    # end __mul__

    def __rmul__(self, other):
        """Copy and return the multiplied value. Uses * operator (2 * mycake)."""
        return self.__mul__(other)
    # end __rmul__
# end class Cake


class ChocolateCupcake(Cake):
    """Create chocolate cupcakes."""
    def init_ingredients(self):
        """Initialize ingredients."""
        super().init_ingredients() # Cake.init_ingredients(self)
        self.name = "Chocolate Cupcakes"
        self.servings = 12
        self.flour = 12
        self.sugar = 14
        self.chocolate_chips = 8
    # end init_ingredients
# end class ChocolateCupcake


mycake = Cake()
print(mycake*2)
print(mycake)
mycake *= 3
print()
mycake.show_ingredients()

choco = ChocolateCupcake(2)
print()
choco.show_ingredients()
print()
print("Total Ingredients", mycake+choco)
print()
both = mycake + choco
both.show_ingredients()