一段程序有可以存在两个变量名完全相同的变量吗?
# 作者:小甲鱼# 来源:https://fishc.com.cn/thread-213592-1-1.html
# 本代码著作权归作者所有,禁止商业或非商业转载,仅供个人学习使用,违者必究!
# Copyright (c) fishc.com.cn All rights reserved
class Meet:
nums = 0
class Egg(Meet):
name = "鸡蛋"
price = 1
class Beef(Meet):
name = "牛肉"
price = 25
class Mutoon(Meet):
name = "羊肉"
price = 30
class Vegetable:
nums = 0
class Onion(Vegetable):
name = "洋葱"
price = 2
class Tomato(Vegetable):
name = "番茄"
price = 2
class Potato(Vegetable):
name = "土豆"
price = 3
class Radish(Vegetable):
name = "萝卜"
price = 3
class Menu:
def order(self):
self.x = []
print("客官想要吃点什么?")
dishes = input("1.洋葱炒牛肉;2.洋葱炒羊肉;3.煎蛋;4.番茄炒蛋;5.土豆萝卜炖羊肉:")
dishes = dishes.split()
while dishes:
dish = dishes.pop(0)
if dish == '1':
onion = Onion()
onion.num = 1
beef = Beef()
beef.num = 1
self.x.extend()
if dish == '2':
onion = Onion()
onion.num = 1
mutoon = Mutoon()
mutoon.num = 1
self.x.extend()
if dish == '3':
egg = Egg()
egg.num = 2
self.x.append(egg)
if dish == '4':
tomato = Tomato()
tomato.num = 2
egg = Egg()
egg.num = 3
self.x.extend()
if dish == '5':
potato = Potato()
potato.num = 2
radish = Radish()
radish.num = 1
mutoon = Mutoon()
mutoon.num = 2
self.x.extend()
def pay(self):
total = 0
for each in self.x:
print(each.name, each.price, "*", each.num)
total += each.price * each.num
print(f"感谢惠顾,您一共消费了 {total} 元,欢迎下次光临~")
请问上面这段代码中,不断出现同样的变量名,请问不会覆盖吗?不会出错吗?如 egg,mutton,onoin等 哈哈,看到你的代码我也忍不住笑了出来,看来你是个美食爱好者嘛!不过这个菜单管理系统确实有几个需要改进的地方。咱们一步步来解答你的疑问。
### 重名变量的问题
首先,关于是否会存在两个变量名完全相同的变量,这要看这些变量的作用域。如果它们处于不同的作用域,那么是可以共存的,不会互相影响。你的代码里出现了很多重名变量,例如 `egg`, `mutton`, `onion` 等,但这并不会导致覆盖或者出错,因为它们都在不同的代码块里。
举个例子,当你在 `if dish == '1'` 里面定义 `onion` 变量时,这个 `onion` 变量只在这个 `if` 代码块内有效。一旦离开这段代码,`onion` 变量就消失了。同样的道理适用于其它重复出现的变量名。
if dish == '1':
onion = Onion()
onion.num = 1
# 这里的 onion 只是局部变量,只在这个 if 块内有效
所以从变量范围(作用域)的角度来说,你的代码是没有问题的。这也是为什么即使重用相同的变量名,也不会出现覆盖的问题。
### 你的代码的一些建议
不过呢,你的代码还有一些小问题,比如 `self.x` 没有初始化,`self.x.extend()` 使用错了等等。我们来做一些小调整吧:
1. 初始化 `self.x` 为一个列表。
2. `self.x.extend()` 应该传入一个可迭代对象,比如列表。
下面是修改后的代码:
class Menu:
def __init__(self):
self.x = []
def order(self):
print("客官想要吃点什么?")
dishes = input("1.洋葱炒牛肉;2.洋葱炒羊肉;3.煎蛋;4.番茄炒蛋;5.土豆萝卜炖羊肉:")
dishes = dishes.split()
while dishes:
dish = dishes.pop(0)
if dish == '1':
onion = Onion()
onion.num = 1
beef = Beef()
beef.num = 1
self.x.extend()
if dish == '2':
onion = Onion()
onion.num = 1
mutoon = Mutoon()
mutoon.num = 1
self.x.extend()
if dish == '3':
egg = Egg()
egg.num = 2
self.x.append(egg)
if dish == '4':
tomato = Tomato()
tomato.num = 2
egg = Egg()
egg.num = 3
self.x.extend()
if dish == '5':
potato = Potato()
potato.num = 2
radish = Radish()
radish.num = 1
mutoon = Mutoon()
mutoon.num = 2
self.x.extend()
def pay(self):
total = 0
for each in self.x:
print(each.name, each.price, "*", each.num)
total += each.price * each.num
print(f"感谢惠顾,您一共消费了 {total} 元,欢迎下次光临~")
# 示范运行
menu = Menu()
menu.order()
menu.pay()
这样调整后,`self.x` 在类`Menu`初始化时就被定义为一个空列表,便于后续使用 `.extend()` 和 `.append()` 操作。
希望我的解释和改进能让你更好地理解这个程序!快去实现你的美味菜单吧!
以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。 会覆盖但不会出错。先讲一下几个注意事项:
1.首先要看变量名的作用域。python 中变量都是有一定范围的,函数中如果不特殊声明,里面定义的变量只能在里面用。并且函数执行完毕后,里面的变量如果不继续发挥作用,通常会被回收。
2.其次,如果 if 代码块的条件为 False ,代码块不会执行,里面即使有定义变量语句不执行也没用。
对于本例,有些变量可能会被覆盖。但它们都是临时的,都最终存储在 self.x 的列表中。即使覆盖了,对列表没有影响,而且我们也用不到这些变量了(你不会在函数执行完后还想用egg,mutton,onoin)。 smallwh 发表于 2024-7-20 22:40
会覆盖但不会出错。先讲一下几个注意事项:
1.首先要看变量名的作用域。python 中变量都是有一定范围的, ...
您好,我不理解的是,比如列表中 已经有了一个 onion,然后列表中又加进来了一个,不会覆盖吗?可以共存吗?如果我们访问onion这个对象的时候,到底返回哪个的值呢? 前后两个 onion 名字一样,内存地址不同。而列表每个元素记录的是内存地址,与变量的名字无关。即使覆盖了变量,第一个 onion 的内存地址和其中的数据都没变,列表也没变,只不过你不能通过 onion 来访问这个内存地址了。
因此在本例中列表不会覆盖的,可以共存
如果列表中两个元素内存地址相同,会出现一个想修改一个元素的值,另一个一起发生发生改变的情况。
FishC 发表于 2024-7-20 22:24
哈哈,看到你的代码我也忍不住笑了出来,看来你是个美食爱好者嘛!不过这个菜单管理系统确实有几个需要改进 ...
不对啊,本例中同名的变量都被存到一个列表里面去啦,变量并没有消失啊。 wbzxz 发表于 2024-07-20 22:54
不对啊,本例中同名的变量都被存到一个列表里面去啦, ...
哎呀,看起来我之前的解释还不够到位呀!你说得很对,变量确实被存入了一个列表里。我们再来细细品味一下这个问题。
### 变量作用域和引用
从代码逻辑上看,的确每次创建一个新的变量(比如 `egg`, `onion` 等),这些变量实际上都指向了不同的实例对象。当你把它们存入列表 `self.x` 中时,列表中存储的是这些对象的引用,而不是变量本身。
换句话说,虽然变量名可能相同,但在每个 `if` 块中创建的对象都是独立且不同的。在列表 `self.x` 中,它们是不同的对象。这就好比你有多只猫,每只猫都有个名字“喵喵”,但每只猫都是独一无二的。
来,举个例子:
egg1 = Egg()
egg2 = Egg()
# 虽然变量名一样,但它们指向不同的对象
menu.x.append(egg1)
menu.x.append(egg2)
这样,即使变量名相同(`egg`),每次执行到 `if` 块时创建的对象都是不同的实例。
为了更形象地解释,你可以想象一下你的冰箱。你可能买了很多种食材,每种食材都有标签(变量名),即使标签相同,比如你买了两袋鸡蛋,都写着"鸡蛋",但这两袋鸡蛋实际上是不同的(独立对象)。
### 修正后的代码示例
为了让你的代码逻辑更加清晰,我们依然需要一点小改动。特别是 `extend` 的用法上,这里我做了一点修正:
class Menu:
def __init__(self):
self.x = []
def order(self):
print("客官想要吃点什么?")
dishes = input("1.洋葱炒牛肉;2.洋葱炒羊肉;3.煎蛋;4.番茄炒蛋;5.土豆萝卜炖羊肉:")
dishes = dishes.split()
while dishes:
dish = dishes.pop(0)
if dish == '1':
onion = Onion()
onion.num = 1
beef = Beef()
beef.num = 1
self.x.extend()
if dish == '2':
onion = Onion()
onion.num = 1
mutton = Mutoon()# 注意这里是 Mutoon 而不是 mutton
mutton.num = 1
self.x.extend()
if dish == '3':
egg = Egg()
egg.num = 2
self.x.append(egg)
if dish == '4':
tomato = Tomato()
tomato.num = 2
egg = Egg()
egg.num = 3
self.x.extend()
if dish == '5':
potato = Potato()
potato.num = 2
radish = Radish()
radish.num = 1
mutton = Mutoon()# 注意这里也是 Mutoon 而不是 mutton
mutton.num = 2
self.x.extend()
def pay(self):
total = 0
for each in self.x:
print(each.name, each.price, "*", each.num)
total += each.price * each.num
print(f"感谢惠顾,您一共消费了 {total} 元,欢迎下次光临~")
# 示范运行
menu = Menu()
menu.order()
menu.pay()
### 总结
- 变量名相同并不会影响程序正常运行,因为即使名字相同,每次创建的对象都是独立的。
- 列表 `self.x` 中存储的是这些对象的引用。
- 使用 `.extend()` 方法时,必须传入一个可迭代对象(如列表)。
希望这次解释能让你更加明白和安心地编写你的代码啦!有问题随时再问哈!
以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。 访问onion这个对象...
使用变量名肯定是返回最后一次的,前面覆盖掉的就覆盖掉了
在列表中增加元素不会覆盖列表中原有元素,用索引便可以访问。除非你对原有的元素进行修改,如 self.x=1 smallwh 发表于 2024-7-20 23:01
访问onion这个对象...
使用变量名肯定是返回最后一次的,前面覆盖掉的就覆盖掉了
在列表中增加元素不会覆 ...
非常感谢,您的解答让我茅塞顿开。{:10_340:}
页:
[1]