描述器
一.__new_的用法(这个也是默认调用的)
这个也叫单例模式,因为一直就是一个实例
class Earth:
def __new__(cls, *args, **kwargs):
if not hasattr(cls, 'instance'):
cls.instance = super().__new__(cls)
return cls.instance
def __init__(self):
Earth.name = 'earth'
e = Earth()
print(e)
a = Earth()
print(a)
首先说一下,这个__new__调用是在__init__前的,因为__new__先创建一个实例,__init__才继续赋值什么的,而这个演示的__new__是改写了默认的new,用来判断一下是否存在,这样可以知道是否已经实例化过了,可以大大的节省内存。
二.对象属性的增删改查
2.1 增
class Person:
def __init__(self, name):
self.name = name
one = Person("zxc")
Person.num = 1 # 第一种,通过句点法来增加
print(one.num)
setattr(one, "nu", "lalal") # 第二种,通过内置函数setattr来实现,这种一定要有实例对象
print(one.nu)
one.__setattr__('n',444) # 第三种,通过魔术方法
print(one.n)
其实内置函数都是所对应的魔术方法来实现的,这也解释为什么一定得有实例对象而不能凭空出现
2.2 删
class Person:
def __init__(self, name):
self.name = name
one = Person("zxc")
delattr(one, "name")
print(one.name)
one.__delattr__(one)
2.3 改
class Person:
def __init__(self, name):
self.name = name
one = Person("zxc")
one.name = "llla"
print(one.name)
setattr(one, "name", "feifei")
print(one.name)
one.__setattr__("name", 666)
print(one.name)
2.4 查
class Person:
def __init__(self, name):
self.name = name
one = Person("zxc")
print(one.name)
print(hasattr(one, "name")) #第一种查找方式,通过hasattr来实现查找,这个函数再__new__方法中调用过
print(getattr(one, "name")) #这是相应得配套得方法,先通过hasattr来了解是否有,然后通过getattr来直接读取
print(one.__getattribute__("name")) #这是对应的第二种得魔术方法
三.描述符
class Cat:
def __get__(self, instance, owner):
return 6666
def __set__(self, instance, value):
print(777)
def __delete__(self, instance):
print(8888)
class Person:
def __init__(self, name):
self.name = name
test = Cat()
c = Person("ZXC")
print(c.test)
c.test = 'true'
print(c.test)
del c.test
这个相当于在一个类中去使用另一个实例对象,而实例对象得每个方法对应为默认调用,每个都有自己得方式
在类里面访问另一个实例
装饰器
本质就是闭包
一.单层装饰器
def test1(func):
def test2():
print("调用之前")
func()
print("调用之后")
return test2
def f1():
print("功能模块")
f1 = test1(f1)
f1()
这个第二种
def test1(func):
def test2():
print("调用之前")
func()
print("调用之后")
return test2
@test1
def f1():
print("功能模块")
# f1 = test1(f1)
f1()
可以看出是一样得效果的,当然这都是没有参数的,哪有参数的怎么做呢
def test1(func):
def test2(*args, **kwargs):
print("调用之前")
func(*args, **kwargs)
print("调用之后")
return test2
@test1
def f1(a):
print("功能模块")
print(a)
# f1 = test1(f1)
f1(5)
@test1
def f2(a):
print("功能模块1")
print(a)
f2(4)
这里的关键就是动态参数,适应性强
二.多层装饰器
def test1(func):
def test2(*args, **kwargs):
print("调用之前")
func(*args, **kwargs)
print("调用之后")
return test2
def test0(func):
def test2(*args, **kwargs):
print("start")
func(*args, **kwargs)
print("end")
return test2
@test0
@test1
def f1(a):
print("功能模块")
print(a)
# f1 = test1(f1)
f1(5)
多层装饰器和单层装饰器原理差不多