python-面向对象类的内置方法
内置方法
__init__(self [, ...])
- init对象实例化时被调用,该方法不能有返回值
__new__(cls [, ...])
- 对象实例化时第一个被调用的方法
- 默认里面的参数,会原封不动的传给init方法
- 返回一个对象obj,通常返回class类对象,也可以返回其他类对象
# 当继承一个不可变类型时,又需要的时候使用 # 需求:输入字符串,输出的是大写的字符串 class CapStr(str): def __new__(cls,string): string = string.upper() return str.__new__(cls, string) # 调用父类new返回 a = CapStr("i love you") print(a) # 输出 I LOVE YOU
__del__(self)
- 当对象被删除时调用该方法(垃圾回收机制执行时,没有变量名指向这个数据值)
# __del__(self) class C: def __init__(self): print("我是init,我被执行了") def __del__(self): print("我是del,我被执行了") c1 = C() # 执行后,打印 我是init,我被执行了 c2 = c1 # 无打印 c3 = c2 del c3 # 无打印输出 del c2 # 无打印输出 del c1 # 执行后打印,我是del,我被执行了
__str__(self)**
- 当对象被使用print()打印的时候调用
- 当print()输出对象的时候,只要自己定义了__str__方法,那么就会打印从这个方法中return的数据
- __str__方法需要返回一个字符串,当做这个对象的描述
class Cat: def __init__(self, new_name, new_age): self.name = new_name self.age = new_age def __str__(self): """自定义 返回一个对象的描述信息""" # print(num) return "名字是:%s , 年龄是:%d" % (self.name, self.age) c1 = Cat("Tom", 8) print(c1) # 打印:名字是:Tom , 年龄是:8
__repr__(self)
- 与__str__类似,当打印容器类型时不同
class A: def __init__(self, name): self.name = name def __str__(self): return "name:%s,----->from str" % self.name def __repr__(self): return "name:%s,----->from repr" % self.name a1 = A("jack") a2 = A("cindy") print(a1) # name:jack,----->from str p = [a1, a2] print(p) # [name:jack,----->from repr, name:cindy,----->from repr] # 当__repr__注释掉时,仅使用__str__时,打印的是地址
- print单独一个对象,如print(a1)时,str和repr具有相同的功能,同时定义str和repr时,调用str
- print对象的容器类型是,repr可以打印每个对象的字符串信息,str不行
属性访问:
__getattr__(self, name)
- 当用户试图通过点调用一个不存在的属性时被触发
__getattribute__(self, name)
- 当该类的属性被访问时调用,存在与否,均为被最先触发
__setattr__(self, name, value)
- 当一个属性被设置时触发;如果该属性不存在就新增,类似于反射中的 setattr(obj, name, value)
__delattr__(self, name)
- 当对象属性被删除时触发
demo:
class C: def __getattribute__(self, name): print("getattribute") super().__getattribute__(name) # 调用基类的该方法 # return self.name 会无限循环 def __getattr__(self, name): print("getattr") def __setattr__(self, name, value): print("setattr") super().__setattr__(name, value) # self.name = value 会无限循环 def __delattr__(self, name): print("delattr") super().__delattr__(name) # del self.name 会无限循环 c = C() print(c.x) # 打印 getattributr/getattr c.x = 10 # 打印 setattr print(c.x) # 打印 getattribute del c.x # 打印 delattr
注意:所有的属性方法,注意无限循环
- 可以使用调用基类的相应方法
- 也可以直接操作属性字典,如self.__dict__[key] = value
- 当__getattribute__与__getattr__同时存在时,只会执行__getattribute__,除非__getattribute__在执行过程中抛出异常AttributeError
__getitem__
__setitem__
__delitem__
item 系列以字典的形式访问属性时被调用
以字典key的方式访问是否存在的属性时,都会触发__getitem__,这一点有别于__getattr__
class Foo: def __init__(self, a): self.a = a def __getitem__(self, item): print("__getitem__被触发了") def __getattr__(self, item): print("__getattr__被触发了") f = Foo("word") f["a"] f["b"] #output: __getitem__被触发了 __getitem__被触发了
使用[]设置实例属性时 ,触发__setitem__
class Foo: def __setitem__(self, key, value): print("__setitem__被触发了") def __setattr__(self, key, value): print("__setattr__被触发了") f = Foo() f.x = 10 f["y"] = 10 #output: __setattr__被触发了 __setitem__被触发了
使用[]删除实例属性时 ,触发__delitem__
class Foo: def __init__(self, a, b): self.a = a self.b = b def __delitem__(self, key): print("__delitem__被触发了") def __delattr__(self, key): print("__delattr__被触发了") f = Foo("one", "two") del f.a del f["b"] #output: __delattr__被触发了 __delitem__被触发了
描述符:
描述符是什么:
- 描述符本质是一个新式类,**在这个新式类中,至少实现了__get__()、__set__()、 __delete__()**中的一个或多个,这个也被成为描述符协议。
描述符干什么:
- 描述符的作用是用来代理另一个类的属性(必须把描述符的对象定义成这个类的类属性,不能定义到构造函数中)。
调用属性时,触发__get__()
**为属性赋值时,触发、__set__()**
采用del删除属性时,触发 __delete__()
__get__
__set__
__delete__
定义一个描述符:下面这个新式类就是描述符
class Foo: def __get__(self, instance, owner): print("我是get...") def __set__(self,instance, value): print("我是set...") def __delete__(self, instance): print("我是delete...")
描述符类实例化的对象,进行属性操作并不会触发这三个方法的执行
描述符分两种:
- 数据描述符,至少含有__get__和 __set__ 的
- 非数据描述符,没有实现 __set__的
描述符严格遵循优先级,优先级由高到低分别是:
- 类属性
- 数据描述符
- 实例属性
- 非数据属性
- 找不到的属性触发__getattr__()
相关推荐
chensen 2020-11-14
lwnylslwnyls 2020-11-06
ATenhong 2020-10-15
yanzhelee 2020-10-13
佛系程序员J 2020-10-10
guojin0 2020-10-08
佛系程序员J 2020-10-08
bluewelkin 2020-09-16
wwzaqw 2020-09-04
zhongdaowendao 2020-09-02
favouriter 2020-08-18
奎因amp华洛 2020-08-15
一青年 2020-08-13
千锋 2020-08-10
nangongyanya 2020-08-09
dongxurr 2020-08-08
明天你好 2020-08-03
kyelu 2020-08-03
Ashes 2020-08-03