如何将来自不同函数的两个局部变量加在一起?
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()
我正在尝试编写一个程序来计算制作蛋糕所需的某些成分的数量,然后将这些数量加在一起计算出每种成分总共需要多少。
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()