内建属性
常用内建属性:
1. __init__ 构造初始化函数 触发:创建实例后,赋值时使用,在__new__后
2. __new__ 生成实例所需属性 触发:创建实例时
3. ___class__ 实例所在的类 触发:实例.__class__
4. __str__ 实例字符串表示,可读性 触发:print(类实例),如果没有实现,则使用repr结果
5. __repr__ 实例字符串表示,准确性 触发:类实例 回车 或者print(类实例)
6. __del__ 析构 触发:del 删除实例
8. __dict__ 实例自定义属性 触发:vars(实例.__dict__)
9. __doc__ 类文档,子类不能继承 触发:help(类或实例)
10. __getattribute__ 属性访问拦截器 触发:访问实例属性时
11. __bases__ 类的所有父类构成元素 触发:类名.__bases__
部分示例:
- getattribute
作用,可以记录对属性的访问
class Test:
def __init__(self, subj):
self.subject1 = subj
self.subject2 = "cpp"
def __getattribute__(self, item):
"""属性拦截器,当访问属性时,就会调用此方法,item为实例的属性名,即访问哪个属性,就默认把哪个属性的名字传进来"""
if item == "subject1":
"""如果访问的是subject1属性,则从这里走"""
print("log subject1")
return "redirect python"
else:
return object.__getattribute__(self,item)
def show(self):
print("hello world")
a = Test("python")
print(a.subject1) #访问属性,调用属性拦截器
print(a.subject2)
a.show() #会发现此处也调用了getattribute,并将函数名作为参数传入了。具体分为两步,1. 以函数名为参数调用getattribute,然后将返回值代替括号之前的部分,即,返回值为函数名称,企图调用该函数。
#因此,如果在getattribute处的else中,如果不return object.__getattribute__(self, item),就会报错
【重点】
实际上,对象中不会有函数,仅仅是有变量,在创建对象时,对于其方法,只是有一个名称和函数名一样的属性,该属性指向了一个函数,所以通过"属性名()"的形式可以调用该方法
**注意事项**
在getattribute中,不能再次出现对属性(self.***)的访问,否则会出现对getattribute的递归调用,无穷无尽
class Person:
class Person:
def __getattribute__(self, item):
print("hello world")
if item.startswith("a"):
return "haha"
else:
self.test()
return None
def test(self):
print("heiehi")
t = Person()
print(t.aaaa) #虽然没有aaaa这个属性,但是还是会调用getattribute方法
t.b #调用getattribute属性,返回test属性,但是这又是对属性的一次访问,所以还会调用getattribute属性,依次循环,所以在getattrubute中再次出现对属性的访问
网友评论