一、new方法:
class Base:
def __new__(cls,*args,**kwargs): # 魔术方法 作用是在初始化之前创建实例。 cls:类本身
print('我是new方法')
print(cls)
instance = object.__new__(cls) # 调用object类 创建实例
print('instance:',instance)
return instance
def __init__(self):
print('我是init方法')
a = Base()
print('a:',a)
四个点理解__new__方法:
1、__new__方法是在类创建实例的时候 自动调用的。
2、实例是通过类里面的__new__方法是在 (object) 类 创建出来的。
3、先调用__new__方法创建 实例,再调用 __init__方法初始化实例。
4、__new__方法,后面括号里的cls代表 的是类本身
单例模式 # new方法的一个应用
class Base:
_instance = None # 存放实例
def __new__(cls, *args, **kwargs): # 魔术方法 new 作用 创建实例 cls 类本身
if cls._instance == None: # 判断是否实例化过
cls._instance = object.__new__(cls) # 调用object类 创建实例
return cls._instance
else:
return cls._instance
a = Base()
b = Base()
print(a,b)
单例模式实现的原理:通过重写 __new__方法,让__new__只能 进行一次实例创建。
注意:
1. _instance = None 中的_instance是实例属性
2. object.__new__(cls) 是什么? 是调用父类的new方法
3. cls 是类本身,self是实例
4. 单例模式 节省内存
二、定制属性访问
class Base:
name = 123
job = '程序员'
def __getattr__(self, item): # item 你传入的属性名
print('No This Attribute %s'%item)
a = Base()
- 查
print(hasattr(a,'name')) # 判断有没有属性
print(getattr(a,'namea'))
print(a.__getattribute__('name'))
- 改
a.name = '老王'
print(getattr(a,'name'))
setattr(a,'name','小明')
print(getattr(a,'name'))
- 增
a.age = 30
print(getattr(a,'age'))
setattr(a,'sex','男')
print(getattr(a,'sex'))
- 删
del a.sex
print(getattr(a,'sex'))
a.__delattr__('age')
print(getattr(a,'age'))
getattr(a,'sdsd')
- 可以不返还错误的方法
re = Rectangle(3, 4) # 矩形类实例def __getattr__(self, item): print('No This Attribute')
getattr(re,'aaa') # aaa属性不存在时,如果定义了此方法,则调用方法
三、描述符
- get、set、delete三个魔术方法组合在一起,就是描述符
class Base:
name = '老万'
def __get__(self, instance, owner):
print('get')
def __set__(self, instance, value):
print('set')
def __delete__(self, instance):
print('delete')
class A:
base = Base()
a = A()
print(a.base)
四、装饰器
- 函数装饰器:实际上是一个闭包:
def A():
def B():
print('啦啦啦,我是闭包')
return B
A()()
- 装饰器的本质是函数,能够实现在不修改原函数的基础上,添加新的功能
def speak(fun): # fun 函数名
def deep(*args,**kwargs):
print('汪汪汪')
b = fun(*args,**kwargs)
return b
return deep
@speak # @ 是调用装饰器的关键字符,作用是:test = speak(test) --> deep
def test(name,age):
print('%s哈哈哈'%name)
return age
a = test('老王',12) # test() ---> deep()
print(a)
- python自带的三个内置装饰器
class Base:
name = '哈哈哈'
@property # 让这个方法变成属性
def eat(self):
return '吃吃吃'
@staticmethod # 作用 断开与类的联系 没有self
def drink():
return '喝喝喝'
@classmethod # 作用 传入 cls
def run(cls): # 类本身
return '运动'
a = Base()
print(a.eat)
print(a.drink())
print(a.run())
- 类装饰器:
类也可以做装饰器,但是必须实现 __init__ 和 __call__ 方法
class My_de:
def __init__(self,fun):
self.fun = fun
def __call__(self, *args, **kwargs):
a = self.fun(*args, **kwargs)
print('旺旺旺')
return a
@My_de # test = My_de(test)
def test(name):
print('%s啦啦啦'%name)
test('小黄')