鱼C论坛

 找回密码
 立即注册
查看: 2430|回复: 6

[已解决][课后作业] 第061讲:类和对象(IV)求助

[复制链接]
发表于 2023-2-20 11:18:18 | 显示全部楼层 |阅读模式

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

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

x
动手环节里的请利用 __bases__ 属性,获取一个类的 MRO 顺序,
源代码为:
def get_bases(cls, count=0):
    # 利用count记录递归级数
    for i in range(count):
        print("-", end=" ")
    print(cls)

    if cls.__bases__[0] is not object:
        for each in cls.__bases__:
            count += 1
            get_bases(each, count)
            count -= 1
假设类D继承自类A、B、C,类A、B、C都继承自类str
使用 __bases__ 属性获得的是这样的形式(<class '__main__.A'>, <class '__main__.B'>, <class '__main__.C'>),进行循环的时候,会出现each是<class '__main__.A'>的情况,当传入的参数是<class '__main__.A'>时,<class '__main__.A'>.__bases__无法显示它的父类。
只有<class '__main__.A'>等价于类A,该循环才能正常进行,这是否说明在python中<class '__main__.A'>等于类A呢?
最佳答案
2023-2-20 21:08:15
在Python中,<class '__main__.A'>和类A并不完全等价。<class '__main__.A'>是指向类A的类型对象的引用,它本身也是一个对象,而类A则是这个类型对象创建出来的实例对象。

在使用__bases__属性获取类的父类时,返回的是一个元组,其中的每个元素都是一个类型对象的引用。在该循环中,每次迭代都会传递一个类型对象的引用,并尝试使用__bases__属性获取其父类,如果该类型是最顶层的基类object,那么__bases__属性将返回一个空元组,否则将返回一个包含所有父类类型对象的元组。

在循环中使用each.__bases__获取每个类的父类,其中each是一个类型对象的引用,所以<class '__main__.A'>.__bases__无法获取到它的父类。要获取类A的父类,可以使用类A本身,如A.__bases__。

因此,<class '__main__.A'>和类A并不完全等价,但可以通过A.__class__获得类A对应的类型对象的引用,从而在循环中正确获取到其父类。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2023-2-20 12:47:52 | 显示全部楼层
<class '__main__.A'> 不就是表示的类A 吗?他之所以以 <class '__main__.A'> 的形式输出,

是因为在类的 __str__ 方法中定义好了输出形式
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-2-20 14:26:45 | 显示全部楼层
所以(<class '__main__.A'>, <class '__main__.B'>, <class '__main__.C'>)意思是(类A,类B,类C)咯
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-2-20 21:08:15 | 显示全部楼层    本楼为最佳答案   
在Python中,<class '__main__.A'>和类A并不完全等价。<class '__main__.A'>是指向类A的类型对象的引用,它本身也是一个对象,而类A则是这个类型对象创建出来的实例对象。

在使用__bases__属性获取类的父类时,返回的是一个元组,其中的每个元素都是一个类型对象的引用。在该循环中,每次迭代都会传递一个类型对象的引用,并尝试使用__bases__属性获取其父类,如果该类型是最顶层的基类object,那么__bases__属性将返回一个空元组,否则将返回一个包含所有父类类型对象的元组。

在循环中使用each.__bases__获取每个类的父类,其中each是一个类型对象的引用,所以<class '__main__.A'>.__bases__无法获取到它的父类。要获取类A的父类,可以使用类A本身,如A.__bases__。

因此,<class '__main__.A'>和类A并不完全等价,但可以通过A.__class__获得类A对应的类型对象的引用,从而在循环中正确获取到其父类。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-2-20 21:28:32 | 显示全部楼层
在 Python 中,每个类都有一个唯一的对象,也称为元类,表示这个类的类型。因此,类A、B、C、D都是对象,它们各自有一个唯一的元类,并通过 __bases__ 属性连接到它们的父类。

<class '__main__.A'> 是类A的表示方式,其中 __main__ 表示当前模块的命名空间。在 Python 中,每个模块都是一个对象,也有一个唯一的名称。因此,如果定义类A在当前模块中,那么 <class '__main__.A'> 和 A 是等价的,都引用了同一个类对象。

但是,如果类A定义在另一个模块中,那么 <class 'other_module.A'> 和 A 就不等价了,因为它们引用了不同的类对象。所以说,在 Python 中,类的标识符包括它的名称和命名空间,只有同时匹配才能表示同一个类。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-2-21 16:15:36 | 显示全部楼层
谢谢各位的帮助了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-2-21 18:07:13 | 显示全部楼层
ouyunfu 发表于 2023-2-20 21:08
在Python中,和类A并不完全等价。是指向类A的类型对象的引用,它本身也是一个对象,而类A则是这个类型对象 ...

<class '__main__.A'> 就是指的类A本身,只不过它是在 __str__ 里面定义的输出形式,只是给人看的,

你当然不能直接拿它来用了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-11-12 12:20

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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