Peteryo01223 发表于 2021-2-2 10:09:37

Python 关于类的一个问题

本帖最后由 Peteryo01223 于 2021-2-2 10:11 编辑

我的问题:标准代码和运行结果,如下。运行结果第16行和17行,我分别输入了1和2,但未对结果产生影响,还是20。其原因,是类的属性(即:变量值)不能被运行程序后的赋值所改变,是吗?请帮我确认一下原因。

标准代码:
class Rectangle:
    length = 5
    width = 4

    def setRect(self):
      print('请输入举行的长和宽。。。')
      self.length = float(input('长:'))
      self.width = float(input('宽:'))

    def getRect(self):
      print('这个举行的长是:%.2f, 宽是:%.2f' % (self.length, self.width))

    def getArea(self):
      return self.length * self.width

运行结果:
>>> rect = Rectangle()
>>> rect.getRect()
这个矩形的长是:5.00,宽是:4.00
>>> rect.setRect()
请输入矩形的长和宽...
长:3.5
宽:5
>>> rect.getRect()
这个矩形的长是:3.50,宽是:5.00
>>> rect.getArea()
17.5
>>> Rectangle().getRect()
这个矩形的长是:5.00,宽是:4.00
>>> Rectangle().setRect()
请输入矩形的长和宽...
长:1
宽:2
>>> Rectangle().getArea()
20

qiuyouzhi 发表于 2021-2-2 10:19:05

因为你后来又重新实例化了一个Rectangle,而你没有给它设置长和宽的属性,
所以结果是20。

sunrise085 发表于 2021-2-2 10:28:43

本帖最后由 sunrise085 于 2021-2-2 10:32 编辑

类属性也可以修改,但是你在运行结果中,从来没有修改过类属性,修改的一直都是实例化属性
你写的方法setRect方法,只修改了实例属性,没有修改类属性,因此类属性length和width一直没有变过。
修改类属性,需要使用类名称修改,如下:
Rectangle.length=2
可以看看我写过的这个总结,希望对你有帮助。
python细节之8、类属性(方法)和类实例化属性(方法)

°蓝鲤歌蓝 发表于 2021-2-2 10:45:53

本帖最后由 °蓝鲤歌蓝 于 2021-2-2 11:43 编辑

应该是覆盖了。
这个问题很有意思,很久没遇到这么有意思的提问了。

°蓝鲤歌蓝 发表于 2021-2-2 11:39:12

sunrise085 发表于 2021-2-2 10:28
类属性也可以修改,但是你在运行结果中,从来没有修改过类属性,修改的一直都是实例化属性
你写的方法setR ...

>>> rect = Rectangle()
>>> rect.getRect()
这个矩形的长是:5.00,宽是:4.00
>>> rect.setRect()
请输入矩形的长和宽...
长:3.5
宽:5
>>> rect.getRect()
这个矩形的长是:3.50,宽是:5.00
>>> rect.getArea()
17.5

这一段也没有修改 类属性,可是实例的属性还是改变了的。

°蓝鲤歌蓝 发表于 2021-2-2 11:40:00

本帖最后由 °蓝鲤歌蓝 于 2021-2-2 12:01 编辑

qiuyouzhi 发表于 2021-2-2 10:19
因为你后来又重新实例化了一个Rectangle,而你没有给它设置长和宽的属性,
所以结果是20。

Rectangle().getRect()
这个矩形的长是:5.00,宽是:4.00
>>> Rectangle().setRect()
请输入矩形的长和宽...
长:1
宽:2
>>> Rectangle().getArea()
20

这一段的三个 Rectangle() 都是同一个对象。
补: 说的不够严谨,应该说它们的地址有时候是相同的

°蓝鲤歌蓝 发表于 2021-2-2 12:13:34

本帖最后由 °蓝鲤歌蓝 于 2021-2-2 12:14 编辑

二楼的才是正确答案,在这里补充一下。
>>> Rectangle().getRect()
这个矩形的长是:5.00,宽是:4.00
>>> Rectangle().setRect()
请输入矩形的长和宽...
长:1
宽:2
>>> Rectangle().getArea()
20
这三个 Rectangle() , 是不同的对象,但它们的地址有可能相同。我测试的时候在这里被误导了,还以为三个对象共用一个地址。
因为每个 Rectangle() 被用完后就回收掉了,也就是说运行完 Rectangle().getRect() 之后,第一个 Rectabgle() 就被回收了,此时它的地址也空出来了,所以第二个 Rectangle() 创建时仍然有可能使用该地址。
同理第二个、第三个都是被使用完就被回收了,所以三个 Rectangle() 分别是三个不同的 实例对象。

Peteryo01223 发表于 2021-2-2 13:34:56

qiuyouzhi 发表于 2021-2-2 10:19
因为你后来又重新实例化了一个Rectangle,而你没有给它设置长和宽的属性,
所以结果是20。

谢谢!

Peteryo01223 发表于 2021-2-2 13:39:47

°蓝鲤歌蓝 发表于 2021-2-2 12:13
二楼的才是正确答案,在这里补充一下。

这三个 Rectangle() , 是不同的对象,但它们的地址有可能相同。 ...

这么深奥啊?

°蓝鲤歌蓝 发表于 2021-2-2 13:44:19

Peteryo01223 发表于 2021-2-2 13:39
这么深奥啊?

这个哪里深奥了?
实例化对象你会吧? 那么这三个 Rectangle() 就相当于你分别实例化了三个对象 r1, r2, r3,
那么它们进行的操作( set/get ) 就互不影响,所以你提问里的那个 length 和 width 才会没改变。

Peteryo01223 发表于 2021-2-2 13:55:04

本帖最后由 Peteryo01223 于 2021-2-2 14:07 编辑

°蓝鲤歌蓝 发表于 2021-2-2 13:44
这个哪里深奥了?
实例化对象你会吧? 那么这三个 Rectangle() 就相当于你分别实例化了三个对象 r1, r2, ...

好的,我又重新读了一遍,感觉明白了。感谢详细解释,受益匪浅!

以后,我再使用类的时候,为了保持一致,就先用 rect = Rectangle() 这种形式,再操作rect.getRect() 等等。比每次都直接调用 Rectangle() 保险,否则又会出现对象一次一变了。

我觉得有点儿像是:下载 windows, 然后买电脑。哈哈。如果,下载的windows,存在了一个硬盘里,每次装到电脑上再卖出去,就能保持一致。但,如果下载的 windows,每次都是临时去微软官网download,再把PC卖出去,很可能前后下载的的版本,已经被更新了,win7 win8 win9等等,这样,装在pc上再卖出去,这些电脑都不一样了,都是不同的对象。

我的例子中,临时赋值 1 和 2,等于是自己给 windows “改”了参数。但下面又直接从“官网”下载了一次windows,自然其中参数根本没变化。

°蓝鲤歌蓝 发表于 2021-2-2 14:13:20

本帖最后由 °蓝鲤歌蓝 于 2021-2-2 14:14 编辑

Peteryo01223 发表于 2021-2-2 13:55
好的,我又重新读了一遍,感觉明白了。感谢详细解释,受益匪浅!

以后,我再使用类的时候,为了保持 ...

有空还是额外了解一下计算机基础吧。
举个例子:
r = Rectangle()
相当于你在一张纸上画了个 矩形,
rect.getRect()
然后,你获得了这个矩形的长宽
rect.setRect()
你修改了这个矩形的长宽
rect.getArea()
你求得了这个矩形的面积

注:上面的所有操作都是作用在 同一张纸上的同一个矩形 r 上的。

而下面这种
Rectangle().getRect()
你在纸上画了个矩形,并获得了它的长宽,然后把它涂掉了
Rectangle().setRect()
你又在纸上画了个矩形,并修改了它的长宽,然后又把它涂掉了
Rectangle().getArea()
你又又在纸上画了个矩形,并求得了它的面积,然后又又把它涂掉了

注1:上面的操作都是作用在不同的 矩形 上的,它们都互不影响,所以虽然你在第二个矩形上修改了长宽,但是你又把它涂掉了(其实是python自己涂的,这里只是打个比方),所以第三个矩形的长宽根本没改变,就是那个默认的

注2:上面三个矩形可能是在同一张纸上,可能是不同的纸上(其实也不是你决定的,是python决定的),这个纸就相当于 内存地址

注3:规定这里的 纸 上只能画一个 矩形

Peteryo01223 发表于 2021-2-2 14:22:46

°蓝鲤歌蓝 发表于 2021-2-2 14:13
有空还是额外了解一下计算机基础吧。
举个例子:



好的,我思路更清晰了一些了。谢谢。
页: [1]
查看完整版本: Python 关于类的一个问题