一、__new__方法
当所有实例中间封装的数据都相同的情况下 我们去实例化 就可以用__new__
方法
__init__
方法如果两次实例化 是会有两个不同的地址
__new__ : 单例模式
class A:
def __new__(cls, *args, **kwargs):
if not hasattr(cls, "instance"): # 判断是不是已经有实例存在
cls.instance = super().__new__(cls) # 新建一个实例
return cls.instance # 有了的话直接调用
def __init__(self):
self.name = "王福鑫"
one = A()
print(one, id(one))
two = A()
print(two, id(two)) #相同的内存地址
二、对象属性的增删改查
1、增
无则增,有则改
class Rectangle:
def __init__(self, length, width):
self.length = length
self.width = width
def area(self):
areas = self.length * self.width
return "面积是:{}".format(areas)
a = Rectangle(66, 88)
a.num = 6 #第一种增加方法
setattr(a, "num", 6) #第二种增加方法
a.__setattr__("num", 6) #第三种增加方法
print(a.num)
a.num = 8
setattr(a, "num", 10)
a.__setattr__("num", 12)
print(a.num) #无则增,有则改
2、查
print(hasattr(a, 'num')) # bool值
print(getattr(a, 'num')) # 获取属性值
print(a.__getattribute__('num')) # 获取属性值
3、删
del a.num
delattr(a, "num")
a.__delattr__("num")
#当属性不存在时,调用魔术方法,实现不报错
def __getattr__(self, item):
print("no attribute")
魔术方法,给了我们一个自定义的接口,函数执行的底层其实就是去调用了魔术方法,只需要修改一下对应的魔术方法,就实现自定义
class A:
def __get__(self, instance, owner):
print("__get__")
def __set__(self, instance, value):
print("__set__")
def __delete__(self, instance):
print("__delete__")
class B:
a = A() # 把A的实例对象拿来做了B的类属性,描述器
def __init__(self):
self.name = "句号"
b = B() # 类的实例化
print(b.name) # 获取对象属性
b.a # 获取B的类属性(A的实例),会去执行__get__
b.a = 88 # 重新赋值,会去执行__set__
del b.a # 删除 ,会去执行__delete__
三、装饰器
1、一个装饰器
本质还是一个闭包
def outer(func):
def inner():
print("前增功能")
func()
print("后增功能")
return inner
@outer # 1.执行outer函数,并将下方的函数名作为参数赋值给了outre函数 2.将outer函数的返回值重新赋值给了下方函数
def f1():
print("原功能")
f1()
有参数为了方便接收不同的参数个数的每个函数,*args, **kwargs
def outer(func):
def innt(*args, **kwargs):
print("前增")
func(*args, **kwargs)
print("后增")
return innt
@outer
def f1():
print("没有参数")
f1()
@outer
def f2(a):
print(a)
f2(6)
@outer
def f3(a, b):
print(a + b)
f3(5, 6)
@outer
def f4(a, b, c):
print(a + b + c)
f4(5, 6, c=7)
2、多个装饰器
def outer_0(func):
def innt(*args, **kwargs):
print("start")
func(*args, **kwargs)
print("ebd")
return innt
def outer(func):
def innt(*args, **kwargs):
print("前增")
func(*args, **kwargs)
print("后增")
return innt
@outer_0
@outer
def f1():
print("原功能")
f1()
3、内置装饰器
class Cat:
name = "猫"
def __init__(self, color, eat):
self.color = color
self.eat = eat
def print_cat(self):
print("{},{}".format(self.color, self.eat))
@classmethod
def funcl(cls):
print("OK")
kitty = Cat('white', 'food')
kitty.print_cat()
kitty.funcl()
Cat.funcl()
@property # (方法变属性)
class Cat:
name = "猫"
def __init__(self, color, eat):
self.color = color
self.eat = eat
@property # (方法变属性)
def print_cat(self):
print("{},{}".format(self.color, self.eat))
@classmethod
def funcl(cls):
print("OK")
kitty = Cat('white', 'food')
kitty.print_cat #可以直接这样调用不用()
@staticmethod #静态方法(解绑)
class Cat:
name = "猫"
def __init__(self, color, eat):
self.color = color
self.eat = eat
@property # (方法变属性)
def print_cat(self):
print("{},{}".format(self.color, self.eat))
@classmethod
def funcl(cls):
print("OK")
@staticmethod
def func():
print("不需要self参数也能运行")
print("不需要实例也能运行")
kitty = Cat('white', 'food')
kitty.func()
Cat.func()
4、类做装饰器
class TestClass:
"""这是一个用来做装饰器的类"""
def __init__(self, func):
self.func = func
def __call__(self, *args, **kwargs):
print("__call__")
print("前增")
self.func()
print("后增")
@TestClass # 类的实例不能直接被调用 想要调用 必须要定义一个__call__方法
def f():
print("原功能")
f()