25-高级特性之内建属性(1)

1. 常用的内建属性:

name 说明 触发时机及功能
__init__() 对创建好的对象进行初始化 在__new__()之后,对象属性要赋值时使用
__new__() 创建类的对象 创建实例,为实例分配内存
__class__ 实例所在的类 实例名.__class__
__str__() 实例的字符串表示 print(实例名),如果没有自定义__str__(),默认使用__repr__()
__repr__() 实例的字符串表示 控制台下写实例名并回车; print(repr(实例名))
__del__() 析构函数 del 实例名
__dict__ 实例的自定义属性 vars(实例名.__dict__)
__doc__ 类文档。子类不继承 help(类或实例)
__getattribute__() 属性访问拦截器 访问实例属性时
__bases__ 类的所有父类 类名.__bases__
  • 测试__getattribute__()

    class School(object):
    def init(self,subject1):
    self.subject1 = subject1
    self.subject2 = 'cpp'
    #属性访问时拦截器,打log
    def getattribute(self,obj): #重写属性的访问拦截器
    if obj == 'subject1':
    print('log subject1')
    return 'redirect python'
    else: #测试时注释掉这2行试试
    return super().getattribute(obj) #使用父类的__getattribute__(),等价于没有重写
    s = School("python")
    print(s.subject1)
    print(s.subject2)

  • 使用__getattribute()的坑:

    class Person(object):
    def getattribute(self,obj):
    print("---test---")
    if obj.startswith("a"):
    return "hahha"
    else:
    return self.test #因为等价于调用当前对象的属性,又会去调用__getattribute__,然后死循环出不来
    def test(self):
    print("heihei")
    t = Person()
    t.a #返回hahha
    t.b #会让程序死掉

注意在__getattribute__中禁止使用self.属性(或者self.方法(),它也会去执行属性访问拦截器),因为它会递归进入__getattribute__,而且是个死循环,最终程序崩溃。

原文地址:https://www.cnblogs.com/LS1314/p/8504493.html