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__
,而且是个死循环,最终程序崩溃。