1,new方法:
类每次实例化时都会创建一个新的对象,
class Textcls:
# cls 是指类本身,
def __new__(cls, *args, **kwargs): # 在 __init__ 前触发,
if not hasattr( cls,'inst' ): # 判断是否有 inst 的属性
cls.inst = super().__new__(cls) # 调用 __new__ 方法,为当前类创建空间
# 如果没有 创建属性给实例,此时 属性= c1 return cls.inst
# 如果有 返回 c1, 此时 c1 = c2 def __init__(self):
print('') c1 = Textcls() # 第一次实例 c1,
c2 = Textcls() # 第二次实例 c1 给c2
print(id(c1), id(c2))
# 创建两个实例 ,内存地址一样,所以两个实例拿完相同,
# 目的为了文件打开保存是一一的,
2, 定制属性访问 (自醒) 反射
hasattr( cls,'inst' ) 判断类 cls 中有没有 inst 的属性 存在返回 真
delattr ( cls,'inst' ) 删除类 cls 中的 inst 属性
gelattr ( cls,'inst' ) 获取类 cls 中的 inst 值,相当于:cls .inst
selattr ( cls,'inst','已经存在?' ) 如果 inst 在类 cls 中已经存在,则会用 “已经存在?”这个值覆盖原 inst 的值 ,
如果不存在,则添加这个属性
__getattr__(): 的使用,
class Textcls:
def __getattr__(self, item):
print('你调用的属性不存在,') c = Textcls()
getattr(c,'a') ## ------》》》 你调用的属性不存在,
如果一个不存在的属性被调用,则会触发 __getattr__(): 的方法
3,描述符
class MyAttribute:
def __get__(self, instance, owner):
print("get") def __set__(self, instance, value):
print('set') def __delete__(self, instance):
print("delete") def __del__(self):
print('del') class MyClass:
m = MyAttribute() # 用实例做属性
def __del__(self):
print('del MyClass') c = MyClass()
c.m # 调用属性,如果属性是个实例,会触发 __get__方法
# 一个实例调用另一个实例, c.m = 123 # 修改实例属性时,果属性是个实例, 会触发 __set__
del c.m # 修改实例属性时,会触发 __set__
4,装饰器
def f1(f):
print('f1')
def f2():
print('f2')
return f2 def f():
print('f') f1(f)() ## f1(f)() 相当于
# a = f()
# f1(a)
f1() 返回 f2,这时 f1() 可以做另一个函数的 装饰def f1(f):
print('f1')
def f2():
print('f2')
return f2 @ f1 # 语法糖,如果后面是韩式,会直接调用这个函数,
def f():
print('f') f() # 运行该函数时,相当于把这个函数当成参数传进 f1() 中运行,
# 再把返回的 闭包加 () 运行,
内置装饰器:
@property
class Re(): @property # 调用该方法时不会传入 self
def test1(self):
print('a') def test2(self):
print('b') m = Re()
m.test1
m.test2()
@ classmethod
class Tacls(): def f1(self):
print(self) @ classmethod # 会自动传入 类本身,
def f2(cls):
cls().f1()
print('方法 f2') m = Tacls()
m.f1()
m.f2()
@staticmethod
class Re(): @staticmethod # 调用该方法时不会传入 self
def test1(self):
print('a') def test2(self):
print('b') m = Re()
m.test1(self=)