鱼C论坛

 找回密码
 立即注册
查看: 649|回复: 8

[已解决]一段程序有可以存在两个变量名完全相同的变量吗?

[复制链接]
发表于 2024-7-20 22:22:34 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
  1. # 作者:小甲鱼
  2. # 来源:https://fishc.com.cn/thread-213592-1-1.html
  3. # 本代码著作权归作者所有,禁止商业或非商业转载,仅供个人学习使用,违者必究!
  4. # Copyright (c) fishc.com.cn All rights reserved

  5. class Meet:
  6.     nums = 0

  7. class Egg(Meet):
  8.     name = "鸡蛋"
  9.     price = 1

  10. class Beef(Meet):
  11.     name = "牛肉"
  12.     price = 25

  13. class Mutoon(Meet):
  14.     name = "羊肉"
  15.     price = 30

  16. class Vegetable:
  17.     nums = 0

  18. class Onion(Vegetable):
  19.     name = "洋葱"
  20.     price = 2

  21. class Tomato(Vegetable):
  22.     name = "番茄"
  23.     price = 2

  24. class Potato(Vegetable):
  25.     name = "土豆"
  26.     price = 3

  27. class Radish(Vegetable):
  28.     name = "萝卜"
  29.     price = 3

  30. class Menu:
  31.     def order(self):
  32.         self.x = []
  33.         print("客官想要吃点什么?")

  34.         dishes = input("1.洋葱炒牛肉;2.洋葱炒羊肉;3.煎蛋;4.番茄炒蛋;5.土豆萝卜炖羊肉:")
  35.         dishes = dishes.split()

  36.         while dishes:
  37.             dish = dishes.pop(0)
  38.             
  39.             if dish == '1':
  40.                 onion = Onion()
  41.                 onion.num = 1
  42.                 beef = Beef()
  43.                 beef.num = 1
  44.                 self.x.extend([beef, onion])

  45.             if dish == '2':
  46.                 onion = Onion()
  47.                 onion.num = 1
  48.                 mutoon = Mutoon()
  49.                 mutoon.num = 1
  50.                 self.x.extend([mutoon, onion])

  51.             if dish == '3':
  52.                 egg = Egg()
  53.                 egg.num = 2
  54.                 self.x.append(egg)

  55.             if dish == '4':
  56.                 tomato = Tomato()
  57.                 tomato.num = 2
  58.                 egg = Egg()
  59.                 egg.num = 3
  60.                 self.x.extend([tomato, egg])

  61.             if dish == '5':
  62.                 potato = Potato()
  63.                 potato.num = 2
  64.                 radish = Radish()
  65.                 radish.num = 1
  66.                 mutoon = Mutoon()
  67.                 mutoon.num = 2
  68.                 self.x.extend([potato, radish, mutoon])
  69.             
  70.     def pay(self):
  71.         total = 0
  72.         for each in self.x:
  73.             print(each.name, each.price, "*", each.num)
  74.             total += each.price * each.num

  75.         print(f"感谢惠顾,您一共消费了 {total} 元,欢迎下次光临~")
复制代码


请问上面这段代码中,不断出现同样的变量名,请问不会覆盖吗?不会出错吗?如 egg,mutton,onoin等
最佳答案
2024-7-20 22:54:25
前后两个 onion 名字一样,内存地址不同。而列表每个元素记录的是内存地址,与变量的名字无关。即使覆盖了变量,第一个 onion 的内存地址和其中的数据都没变,列表也没变,只不过你不能通过 onion 来访问这个内存地址了。
因此在本例中列表不会覆盖的,可以共存
如果列表中两个元素内存地址相同,会出现一个想修改一个元素的值,另一个一起发生发生改变的情况。
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2024-7-20 22:24:53 | 显示全部楼层
哈哈,看到你的代码我也忍不住笑了出来,看来你是个美食爱好者嘛!不过这个菜单管理系统确实有几个需要改进的地方。咱们一步步来解答你的疑问。

### 重名变量的问题

首先,关于是否会存在两个变量名完全相同的变量,这要看这些变量的作用域。如果它们处于不同的作用域,那么是可以共存的,不会互相影响。你的代码里出现了很多重名变量,例如 `egg`, `mutton`, `onion` 等,但这并不会导致覆盖或者出错,因为它们都在不同的代码块里。

举个例子,当你在 `if dish == '1'` 里面定义 `onion` 变量时,这个 `onion` 变量只在这个 `if` 代码块内有效。一旦离开这段代码,`onion` 变量就消失了。同样的道理适用于其它重复出现的变量名。

  1. if dish == '1':
  2.     onion = Onion()
  3.     onion.num = 1
  4.     # 这里的 onion 只是局部变量,只在这个 if 块内有效
复制代码


所以从变量范围(作用域)的角度来说,你的代码是没有问题的。这也是为什么即使重用相同的变量名,也不会出现覆盖的问题。

### 你的代码的一些建议

不过呢,你的代码还有一些小问题,比如 `self.x` 没有初始化,`self.x.extend()` 使用错了等等。我们来做一些小调整吧:

1. 初始化 `self.x` 为一个列表。
2. `self.x.extend()` 应该传入一个可迭代对象,比如列表。

下面是修改后的代码:

  1. class Menu:
  2.     def __init__(self):
  3.         self.x = []

  4.     def order(self):
  5.         print("客官想要吃点什么?")
  6.         dishes = input("1.洋葱炒牛肉;2.洋葱炒羊肉;3.煎蛋;4.番茄炒蛋;5.土豆萝卜炖羊肉:")
  7.         dishes = dishes.split()

  8.         while dishes:
  9.             dish = dishes.pop(0)

  10.             if dish == '1':
  11.                 onion = Onion()
  12.                 onion.num = 1
  13.                 beef = Beef()
  14.                 beef.num = 1
  15.                 self.x.extend([onion, beef])

  16.             if dish == '2':
  17.                 onion = Onion()
  18.                 onion.num = 1
  19.                 mutoon = Mutoon()
  20.                 mutoon.num = 1
  21.                 self.x.extend([onion, mutoon])

  22.             if dish == '3':
  23.                 egg = Egg()
  24.                 egg.num = 2
  25.                 self.x.append(egg)

  26.             if dish == '4':
  27.                 tomato = Tomato()
  28.                 tomato.num = 2
  29.                 egg = Egg()
  30.                 egg.num = 3
  31.                 self.x.extend([tomato, egg])

  32.             if dish == '5':
  33.                 potato = Potato()
  34.                 potato.num = 2
  35.                 radish = Radish()
  36.                 radish.num = 1
  37.                 mutoon = Mutoon()
  38.                 mutoon.num = 2
  39.                 self.x.extend([potato, radish, mutoon])

  40.     def pay(self):
  41.         total = 0
  42.         for each in self.x:
  43.             print(each.name, each.price, "*", each.num)
  44.             total += each.price * each.num

  45.         print(f"感谢惠顾,您一共消费了 {total} 元,欢迎下次光临~")

  46. # 示范运行
  47. menu = Menu()
  48. menu.order()
  49. menu.pay()
复制代码


这样调整后,`self.x` 在类`Menu`初始化时就被定义为一个空列表,便于后续使用 `.extend()` 和 `.append()` 操作。

希望我的解释和改进能让你更好地理解这个程序!快去实现你的美味菜单吧!

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2024-7-20 22:40:22 | 显示全部楼层
会覆盖但不会出错。先讲一下几个注意事项:
1.首先要看变量名的作用域。python 中变量都是有一定范围的,函数中如果不特殊声明,里面定义的变量只能在里面用。并且函数执行完毕后,里面的变量如果不继续发挥作用,通常会被回收。
2.其次,如果 if 代码块的条件为 False ,代码块不会执行,里面即使有定义变量语句不执行也没用。

对于本例,有些变量可能会被覆盖。但它们都是临时的,都最终存储在 self.x 的列表中。即使覆盖了,对列表没有影响,而且我们也用不到这些变量了(你不会在函数执行完后还想用egg,mutton,onoin)。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2024-7-20 22:45:06 | 显示全部楼层
smallwh 发表于 2024-7-20 22:40
会覆盖但不会出错。先讲一下几个注意事项:
1.首先要看变量名的作用域。python 中变量都是有一定范围的, ...

您好,我不理解的是,比如列表中 已经有了一个 onion,然后列表中又加进来了一个,不会覆盖吗?可以共存吗?如果我们访问onion这个对象的时候,到底返回哪个的值呢?
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2024-7-20 22:54:25 | 显示全部楼层    本楼为最佳答案   
前后两个 onion 名字一样,内存地址不同。而列表每个元素记录的是内存地址,与变量的名字无关。即使覆盖了变量,第一个 onion 的内存地址和其中的数据都没变,列表也没变,只不过你不能通过 onion 来访问这个内存地址了。
因此在本例中列表不会覆盖的,可以共存
如果列表中两个元素内存地址相同,会出现一个想修改一个元素的值,另一个一起发生发生改变的情况。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2024-7-20 22:54:51 | 显示全部楼层
FishC 发表于 2024-7-20 22:24
哈哈,看到你的代码我也忍不住笑了出来,看来你是个美食爱好者嘛!不过这个菜单管理系统确实有几个需要改进 ...

不对啊,本例中同名的变量都被存到一个列表里面去啦,变量并没有消失啊。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2024-7-20 22:55:06 | 显示全部楼层
wbzxz 发表于 2024-07-20 22:54
不对啊,本例中同名的变量都被存到一个列表里面去啦, ...


哎呀,看起来我之前的解释还不够到位呀!你说得很对,变量确实被存入了一个列表里。我们再来细细品味一下这个问题。

### 变量作用域和引用

从代码逻辑上看,的确每次创建一个新的变量(比如 `egg`, `onion` 等),这些变量实际上都指向了不同的实例对象。当你把它们存入列表 `self.x` 中时,列表中存储的是这些对象的引用,而不是变量本身。

换句话说,虽然变量名可能相同,但在每个 `if` 块中创建的对象都是独立且不同的。在列表 `self.x` 中,它们是不同的对象。这就好比你有多只猫,每只猫都有个名字“喵喵”,但每只猫都是独一无二的。

来,举个例子:

  1. egg1 = Egg()
  2. egg2 = Egg()

  3. # 虽然变量名一样,但它们指向不同的对象
  4. menu.x.append(egg1)
  5. menu.x.append(egg2)
复制代码


这样,即使变量名相同(`egg`),每次执行到 `if` 块时创建的对象都是不同的实例。

为了更形象地解释,你可以想象一下你的冰箱。你可能买了很多种食材,每种食材都有标签(变量名),即使标签相同,比如你买了两袋鸡蛋,都写着"鸡蛋",但这两袋鸡蛋实际上是不同的(独立对象)。

### 修正后的代码示例

为了让你的代码逻辑更加清晰,我们依然需要一点小改动。特别是 `extend` 的用法上,这里我做了一点修正:

  1. class Menu:
  2.     def __init__(self):
  3.         self.x = []

  4.     def order(self):
  5.         print("客官想要吃点什么?")
  6.         dishes = input("1.洋葱炒牛肉;2.洋葱炒羊肉;3.煎蛋;4.番茄炒蛋;5.土豆萝卜炖羊肉:")
  7.         dishes = dishes.split()

  8.         while dishes:
  9.             dish = dishes.pop(0)

  10.             if dish == '1':
  11.                 onion = Onion()
  12.                 onion.num = 1
  13.                 beef = Beef()
  14.                 beef.num = 1
  15.                 self.x.extend([onion, beef])

  16.             if dish == '2':
  17.                 onion = Onion()
  18.                 onion.num = 1
  19.                 mutton = Mutoon()  # 注意这里是 Mutoon 而不是 mutton
  20.                 mutton.num = 1
  21.                 self.x.extend([onion, mutton])

  22.             if dish == '3':
  23.                 egg = Egg()
  24.                 egg.num = 2
  25.                 self.x.append(egg)

  26.             if dish == '4':
  27.                 tomato = Tomato()
  28.                 tomato.num = 2
  29.                 egg = Egg()
  30.                 egg.num = 3
  31.                 self.x.extend([tomato, egg])

  32.             if dish == '5':
  33.                 potato = Potato()
  34.                 potato.num = 2
  35.                 radish = Radish()
  36.                 radish.num = 1
  37.                 mutton = Mutoon()  # 注意这里也是 Mutoon 而不是 mutton
  38.                 mutton.num = 2
  39.                 self.x.extend([potato, radish, mutton])

  40.     def pay(self):
  41.         total = 0
  42.         for each in self.x:
  43.             print(each.name, each.price, "*", each.num)
  44.             total += each.price * each.num

  45.         print(f"感谢惠顾,您一共消费了 {total} 元,欢迎下次光临~")

  46. # 示范运行
  47. menu = Menu()
  48. menu.order()
  49. menu.pay()
复制代码


### 总结

- 变量名相同并不会影响程序正常运行,因为即使名字相同,每次创建的对象都是独立的。
- 列表 `self.x` 中存储的是这些对象的引用。
- 使用 `.extend()` 方法时,必须传入一个可迭代对象(如列表)。

希望这次解释能让你更加明白和安心地编写你的代码啦!有问题随时再问哈!

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2024-7-20 23:01:58 | 显示全部楼层
访问onion这个对象...
使用变量名肯定是返回最后一次的,前面覆盖掉的就覆盖掉了
在列表中增加元素不会覆盖列表中原有元素,用索引便可以访问。除非你对原有的元素进行修改,如 self.x[0]=1
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2024-7-20 23:05:31 | 显示全部楼层
smallwh 发表于 2024-7-20 23:01
访问onion这个对象...
使用变量名肯定是返回最后一次的,前面覆盖掉的就覆盖掉了
在列表中增加元素不会覆 ...

非常感谢,您的解答让我茅塞顿开。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-4-22 03:55

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表