python 魔术方法
在Python中,所有用"__"包起来的方法,都称为【魔术方法】(eg:__len __, __init __)。
魔术方法一般是为了让显示器调用的,你自己并不需要调用它们。
一、 特殊属性
mro :python 类有多继承特性,如果继承关系太复杂,很难看出会先调用那个属性或方法。为了方便且快速地看清继承关系和顺序,可以用__mro__方法来获取这个类的调用顺序。
查看属性 dir
返回类或者对象的所有成员名称列表。dir() 函数就是调用__dir__()。
1). 如果dir([obj]) 参数obj包含方法 dir(),该方法将被调用。
2). 如果Obj 不包含 dir(),该方法将最大限度收集属性信息
二、 创建,初始化与销毁
1.面试常问: python 中__new__ , init , __call__的区别?
1). new的功能是在生成对象之前执行
的内容,接受的参数是cls 类, 负责对象的创建
2). init的功能是在对象生成之后执行
的内容, 接受的参数是self 对象, 负责对象的初始化
3). call的功能是在调用对象时执行
的内容, 可以模拟函数的行为.
2.创建对象的步骤
当我们新建一个对象 x=someclass() 的时候,经历的步骤:
1). 第一: __new__先创建类并返回类的实例。
2). 第二: 自动调用__init__来初始化函数的值。
3). 汇总: 第一步和第二步共同构成了【构造函数】。
4). 第三步: 对象生命周期调用结束时,del 方法(构析函数)会被调用。
class Person(object):
def __new__(cls):
print("__new__")
return object.__new__(cls)
def __init__(self):
print("__init__")
def __call__(self, *args, **kwargs):
print('__call__')
def __del__(self):
# 析构方法: 当对象被删除或者从内存释放时自动执行
print("__del__")
p1 = Person()
p1()
3.应用范例:
(1)new魔术方法实现单例模式
(1)new魔术方法实现单例模式
class Person(object):
# 1). 设置类属性, 存储已经创建好的对象。
_instance = None
def __new__(cls, *args, **kwargs):
print("new方法在实例化对象之前执行.....返回对象本身")
# 2). 判断是否已经实例化对象?
if cls._instance:
return cls._instance
else:
self = object.__new__(cls)
cls._instance = self
# 返回父类object的new方法创建的对象.....
return self
def __init__(self):
print("构造方法实例化对象之后执行......")
if __name__ == '__main__':
p1 = Person()
p2 = Person()
print(p1, p2)
(2)new方法实现单例模式改进版
from datetime import date
class Person(object):
def __new__(cls, *args, **kwargs):
print("判断当前类是否拥有instance属性?", hasattr(cls, 'instance'))
if not hasattr(cls, 'instance'):
cls.instance = super(Person, cls).__new__(cls)
return cls.instance
def __init__(self, name):
self.name = name
p1 = Person("张三")
p2 = Person("张xxx")
print("单例模式是否成功? ", p1 is p2)
(2)call魔术方法实现缓存
from functools import lru_cache
class Fib(object):
@lru_cache(maxsize=1000)
def __call__(self, n):
if n in (1, 2