从Python来重新看待面向对象中的类

cloudblaze 2021-06-16 07:31:16

学习了C++、C#还有JAVA之后,我对面向对象中的类与对象之间关系的理解是这样:类是模板、蓝图,在创建类对象的时候依据的是类,也就是说,可能具体属性值可能不同,但所有由同一个类创建的类对象都具有相同的属性。

在了解Python之前,我一直都是这种理解。但后来,我想到了一段Python代码,如下:

class my_class():
    def __init__(self) -> None:
        pass

    def fun1(self):
        self.aaa = 'aaa'
    
    def fun2(self):
        self.bbb = 'bbb'
    
    def fun3(self):
        print(self.aaa, self.bbb)
    
c1 = my_class()
#c1.fun3()

c2 = my_class()
c2.fun1()
#c2.fun3()

c3 = my_class()
c3.fun1()
c3.fun2()
c3.fun3()

直接执行这个程序,输入如下:

aaa bbb

如果把#c2.fun3()注释取消后再执行,则程序出错:

Traceback (most recent call last):
  File "e:\Project\Python\Learning\hello_world\demo.py", line 19, in <module>
    c2.fun3()
  File "e:\Project\Python\Learning\hello_world\demo.py", line 12, in fun3
    print(self.aaa, self.bbb)
AttributeError: 'my_class' object has no attribute 'bbb'

如果把#c1.fun3()注释取消后再执行,则程序同样会出错:

Traceback (most recent call last):
  File "e:\Project\Python\Learning\hello_world\demo.py", line 15, in <module>
    c1.fun3()
  File "e:\Project\Python\Learning\hello_world\demo.py", line 12, in fun3
    print(self.aaa, self.bbb)
AttributeError: 'my_class' object has no attribute 'aaa'

由此看来,c1没有属性'aaa',c2没有属性'bbb',而c3同时具有属性'aaa'和'bbb'。这样的话,均由类'my_class'创建的三个对象,具有属性却都不一样。这有些颠覆我对类及对象的理解。不知是我之前的理解错了,还是说Python语言改变了类及对象的定义?

...全文
813 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
cloudblaze 2021-06-17
  • 打赏
  • 举报
回复

我另外写了一段代码如下:

import random

class my_class():
    def __init__(self) -> None:
        pass

    def fun1(self):
        self.aaa = 'aaa'
    
    def fun2(self):
        self.bbb = 'bbb'
    
    def fun3(self):
        print(self.aaa, self.bbb)
    
c1 = my_class()
if random.randint(1, 100) != 100:
    c1.fun1()
if random.randint(1, 100) != 100:
    c1.fun2()
c1.fun3()

这段代码正确执行的概率是99.99%,但这段代码就是错的。在稍大一点的项目中,只能看到程序报错,很难捕捉这种错误。

cloudblaze 2021-06-17
  • 打赏
  • 举报
回复

其实你没有明白我的意思,我并非是想DEBUG这一段代码使其能够看起来”正常“。我是想表达,用同一个类创建的三个类对象,这三个对象的属性字段都不相同,这还算是同一个类类型吗?一个类的结构竟然要依赖于对象实例对方法的调用顺序,是不是会存在较大的隐患?不可否认,可以通过良好的编码风格来规避这一问题。但这种特性带来的益处是否真的大于其隐藏的风险?对于非常小的项目,这应该不成问题,但如果遇到稍大一点的项目,尤其是依赖程序运行状态而发生的错误很难被捕捉或场景还原。为什么Python不能规避这个问题呢?

文盲老顾 2021-06-16
  • 打赏
  • 举报
回复

class my_class():
    def __init__(self) -> None:
        self.aaa = 'start'
        self.bbb = 'end'
 
    def fun1(self):
        self.aaa = 'aaa'
    
    def fun2(self):
        self.bbb = 'bbb'
    
    def fun3(self):
        print(self.aaa, self.bbb)

在初始化实例的方法里,加上默认值,你再运行你的几个调用,就可以看出区别了

文盲老顾 2021-06-16
  • 打赏
  • 举报
回复

我也刚学python,不知道理解的对不对啊

首先,你的类在实例化时,没有任何属性

aaa也好,bbb也好,都是由实例中的方法创建的,你没有调用相应的方法,那么对应的属性就没有被建立起来,所以会报错

cloudblaze 2021-06-17
  • 举报
回复
@文盲老顾 谢谢,但你没明白我的意思,应该是我的表述没那么清楚。

11,074

社区成员

发帖
与我相关
我的任务
社区描述
创建由Python学习者和社区专家组成的国内最大的第三方Python中文社区,帮助社区成员更好地入门学习、职业成长和应用实践
python学习 企业社区
社区管理员
  • Python全栈技术社区
  • Lumos_zbj
  • 北侠大卫
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

创建由Python学习者和社区专家组成的国内最大的第三方Python中文社区,帮助社区成员更好地入门学习、职业成长和应用实践

  • 这里有最新最全的 Python 学习内容及资源,每月多达4次技术公开课
  • 这里有众多 Python 学习者,陪伴你一起交流成长
  • 这里有专业 Python 社区专家、讲师,帮助你跨越学习瓶颈,解决实操难题
  • 这里有丰富的社区活动,可以开阔眼界,结识更多同伴

【最新活动】:

  1. 周四技术公开课讲师招募中,点击查看详情
  2. “Python 社区专家团” 招募中,点击查看详情

 

试试用AI创作助手写篇文章吧