Python中类的属性、多继承、自省机制中的__mro__、__dict__ 和dir介绍

一、通过类名修改属性和通过类的实例去修改类的属性的区别

    在 Python 中,类的属性可以通过类名或类的实例访问和修改。但是,通过类名修改属性和通过类的实例修改属性之间有一些区别。通过类名修改属性实际上是修改类的属性。这意味着如果你修改了类的属性,那么所有这个类的实例都将受到影响

class Person(object):
    # 类属性
    name = "人类"




Person.name = "小博"
zs = Person()
ls = Person()
print(zs.name, ls.name)
以上案例运行后输出:小博 小博

    通过类的实例修改属性实际上是创建或修改实例的属性。这意味着如果你修改了一个实例的属性,那么只有这个实例会受到影响,而不会影响这个类的其他实例或类本身

class Person(object):
    # 类属性
    name = "人类"




zs = Person()
zs.name = "张三"
ls = Person()
print(zs.name,ls.name,Person.name)
以上代码运行输出:张三 人类 人类

二、多继承的调用顺序

class A:
    def foo(self):
        print("A's foo")




class B(A):
    def foo(self):
        print("B's foo")
        super().foo()




class C(A):
    def foo(self):
        print("C's foo")
        super().foo()




class D(B, C):
    pass




obj = D()
obj.foo()

以上代码运行之后输出如下:

B's foo
C's foo
A's foo

在python3的多继承时,方法解析顺序(MRO)是基于C3算法实现的,会保证解析的顺序是有序的。

三、类的__mro__属性介绍

正如上面的例子,如果你不知道调用顺序,在这里瞎猜的话,你试试

print(D.__mro__),然后就会看到如下输出:

(<class '__main__.D'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.A'>, <class 'object'>)

__mro__ 是一个特殊的属性,它是一个元组,表示了一个类的方法解析顺序(MRO),即查找属性和方法时所遵循的顺序。它是由 Python 在执行继承时自动计算出来的

四、python的自省机制介绍

Python 的自省机制(introspection)是指在运行时(runtime)获取对象的类型、属性、方法等信息的能力。Python 的自省机制非常强大,可以让开发人员在编写程序时更加灵活和高效。

下面列举几个python中提供的内置函数和特殊属性来支持自省机制:

__dict__ :用于存储一个对象的对象的属性和方法,__dict__ 属性允许程序在运行时动态地添加、修改和删除对象的属性和方法,从而实现反射和元编程等高级功能。

在 Python 中,对象的 __dict__ 属性通常可以修改,但有一些对象的 __dict__ 属性是只读的,不能直接修改。下面是一些常见的对象类型及其 __dict__ 属性的修改情况:

1、普通对象实例的 __dict__ 属性可以随意修改,允许动态添加、修改和删除对象的属性和方法

2、类、模块和一些内置对象(比如str)的 __dict__ 属性是只读的,因为类、模块的属性和方法是在定义时确定的,无法在运行时修改,内置对象的属性和方法是由解释器实现的,无法在运行时修改。

3、在 Python 中,int 和 str 对象是不可变对象,它们的 __dict__ 属性是不存在的。因为不可变对象的属性和方法是在定义时确定的,无法在运行时动态地添加、修改和删除,所以它们也不需要 __dict__ 属性来保存属性和方法。

f5b3fcfbf7f9f5dc49f65583d1f45a79.png

dir() 函数:获取对象的属性列表。例如,dir(obj) 可以返回对象 obj 的所有属性和方法的名称列表。

print(dir(str))

['__add__', '__class__', '__contains__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__getnewargs__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__mod__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__rmod__', '__rmul__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'capitalize', 'casefold', 'center', 'count', 'encode', 'endswith', 'expandtabs', 'find', 'format', 'format_map', 'index', 'isalnum', 'isalpha', 'isascii', 'isdecimal', 'isdigit', 'isidentifier', 'islower', 'isnumeric', 'isprintable', 'isspace', 'istitle', 'isupper', 'join', 'ljust', 'lower', 'lstrip', 'maketrans', 'partition', 'replace', 'rfind', 'rindex', 'rjust', 'rpartition', 'rsplit', 'rstrip', 'split', 'splitlines', 'startswith', 'strip', 'swapcase', 'title', 'translate', 'upper', 'zfill']

看完了上面的内容,留一个题目给屏幕前的你,看看以下代码运行后的输出结果是什么呢?

245670517c5cbe1b06257f842e56f109.png

如果看完我写的文章,有收获的话,欢迎点赞转发支持一下哟。想跟着小编一起学的小伙伴,可以私聊哟~

猜你喜欢

转载自blog.csdn.net/liboshi123/article/details/130279070