AI智能
改变未来

『无为则无心』Python面向对象 — 60、魔法属性

[toc]

Python 类中,凡是以双下划线 "__" 开头和结尾命名的成员(属性和方法),这些特殊成员存在着一些特殊含义,都被称为类的特殊成员(特殊属性和特殊方法)。

我们把特殊属性也可以称之为魔法属性,或者内置类属性。

1、魔法属性

__name__

__name__

是用来标识模块名字的一个系统变量。

这里分两种情况:

  • 第一种情况指的是当前运行的模块,那么当前模块
    __name__

    的值就为

    __main__

  • 第二种情况指的是该模块是使用
    import

    导入的模块,那么这个被导入模块的

    __name__

    变量的值为该模块的文件名(去掉

    .py

    )。

示例:

Demo1.py

文件:

# 在当前文件中直接调用__name__属性def my_func():print("我的模块名是", __name__)# __name__属性在模块中可直接调用# 在当期模块中调用# 结果:我的模块名是 __main__if __name__ == "__main__":my_func()

Demo2.py

文件:

# 导入Demo1模块,使用模块中的my_func()方法from Demo1 import *# 执行my_func()方法# 结果:我的模块名是 Demo1my_func()

2、魔法属性

__bases__

Python 为所有类都提供了一个

__bases__

属性,通过该属性可以查看该类的所有直接父类,该属性返回所有直接父类组成的元组。(直接父类)

class A(object):passclass B(A):passclass C(B):passclass D(C,B,A):pass# 类名直接调用__bases__属性print(C.__bases__)print(D.__bases__)"""输出结果:(<class \'__main__.B\'>,)(<class \'__main__.C\'>, <class \'__main__.B\'>, <class \'__main__.A\'>)"""

注意:在类的实例对象中没有

__bases__

属性。

3、魔法属性

__mro__

Python的每一个有父类的类,都有一个与方法解析顺序相关的特殊属性

__mro__

属性, 它是一个

tuple

(元组), 装着方法解析时的对象查找顺序,越靠前的优先级越高。

执行下面的代码:

class A(object):passclass B(A):passclass C(B):pass# 类名直接调用__bases__属性print(C.__bases__)print(C.__mro__)"""输出结果:(<class \'__main__.B\'>,)(<class \'__main__.C\'>, <class \'__main__.B\'>, <class \'__main__.A\'>, <class \'object\'>)"""

说明:

__mro__

属性和

__bases__

属性的区别。

__bases__

属性是查看当前类的直接父类,返回一个元组。

__mro__

属性是指在有继承关系中,包括单继承,多重继承,多层继承中。使用

super

调用父类的方法和属性的时候,优先查找的顺序。

4、魔法属性

__doc__

作用:表示类的描述文档信息。

class Person:"""这里是类的描述类信息。"""def func(self):"""这里是类中方法的描述类信息。"""pass# 因为是属性,不用加()print(Person.__doc__)

输出结果:

5、魔法属性

__module__

__class__

__module__

属性:表示当前操作的对象属于哪个模块。

__class__

属相:表示当前操作的对象的是由哪个类创建的。

# 定义一个类class Person(object):passobj = Person()print(obj.__module__)print(obj.__class__)"""输出结果:__main__ : 表示前挡模块<class \'__main__.Person\'> : 表示该对象属于当前模块中的Python类"""

6、魔法属性

__dict__

列出类中或者对象中的所有成员,以字典的形式返回。这个属性不用我们再类中覆写,类和对象默认自带。

class Person(object):def __init__(self, name, age):self.name = nameself.age = agedef tellMe(self):print(f\'我叫{self.name},今年{self.age}\')# 获取类的所有成员print(Person.__dict__)# # 获取对象的所有成员obj1 = Person(\'美猴王\', "18")obj2 = Person(\'齐天大圣\', "30")print(obj1.__dict__)print(obj2.__dict__)"""输出结果 :类的所有成员:{\'__module__\': \'__main__\',\'__init__\': <function Person.__init__ at 0x0000000002425828>,\'tellMe\': <function Person.tellMe at 0x0000000002425A68>,\'__dict__\': <attribute \'__dict__\' of \'Person\' objects>,\'__weakref__\': <attribute \'__weakref__\' of \'Person\' objects>,\'__doc__\': None}注意:__weakref__,和垃圾回收机制,还有弱引用的知识点有关。对象的所有成员:{\'name\': \'美猴王\', \'age\': \'18\'}{\'name\': \'齐天大圣\', \'age\': \'30\'}"""

注意:从上面的结果可以看出,对象调用

__dict__

属性,没有看到对象中的方法。

  • 类的实例属性属于对象,类的实例方法不属于对象。也就是说
    __dict__

    属性不打印处对象的中方法。

  • 类中的类属性和方法等都属于类。

7、魔法属性

__slots__

Python是动态语言,对于普通的类,可以为类的实例对象赋值任何属性,这些属性会存储在

__dict__

中。

而类中定义了

__slots__

属性,它仅允许动态绑定

__slots__

里边定义的属性。

示例:

# 创建一个Student类class Student():# 定义__slots____slots__ = (\'name\', \'age\')# 创建一个学生对象stu = Student()# 动态添加__slots__属性中定义的属性,可以添加stu.name = \'孙悟空\'stu.age = 18# 而__slots__属性中没有定义的属性,是添加不了的。# 结果:AttributeError: \'Student\' object has no attribute \'addr\'stu.addr = "北京"
赞(0) 打赏
未经允许不得转载:爱站程序员基地 » 『无为则无心』Python面向对象 — 60、魔法属性