重庆分公司,新征程启航
为企业提供网站建设、域名注册、服务器等服务
魔法方法 (Magic Methods) 是Python中的内置函数,一般以双下划线开头和结尾,例如__ init__ 、 __del__ 等。之所以称之为魔法方法,是因为这些方法会在进行特定的操作时会自动被调用。
成都创新互联公司服务项目包括合川网站建设、合川网站制作、合川网页制作以及合川网络营销策划等。多年来,我们专注于互联网行业,利用自身积累的技术优势、行业经验、深度合作伙伴关系等,向广大中小型企业、政府机构等提供互联网行业的解决方案,合川网站推广取得了明显的社会效益与经济效益。目前,我们服务的客户以成都为中心已经辐射到合川省份的部分城市,未来相信会继续扩大服务区域并继续获得客户的支持与信任!
在Python中,可以通过dir()方法来查看某个对象的所有方法和属性,其中双下划线开头和结尾的就是该对象的魔法方法。以字符串对象为例:
可以看到字符串对象有 __add__ 方法,所以在Python中可以直接对字符串对象使用"+"操作,当Python识别到"+"操作时,就会调用该对象的 __add__ 方法。有需要时我们可以在自己的类中重写 __add__ 方法来完成自己想要的效果。
我们重写了 __add__ 方法,当Python识别"+"操作时,会自动调用重写后的 __add__ 方法。可以看到,魔法方法在类或对象的某些事件出发后会自动执行,如果希望根据自己的程序定制特殊功能的类,那么就需要对这些方法进行重写。使用魔法方法,我们可以非常方便地给类添加特殊的功能。
1、构造与初始化
__ new __ 、 __ init __ 这两个魔法方法常用于对类的初始化操作。上面我们创建a1 = A("hello")时,但首先调用的是 __ new __ ;初始化一个类分为两步:
a.调用该类的new方法,返回该类的实例对象
b.调用该类的init方法,对实例对象进行初始化。
__new__ (cls, *args, **kwargs)至少需要一个cls参数,代表传入的类。后面两个参数传递给 __ init __ 。在 __ new __ 可以决定是否继续调用 __ init __ 方法,只有当 __ new __ 返回了当前类cls的实例,才会接着调用 __ init __ 。结合 __ new __ 方法的特性,我们可以通过重写 __ new __ 方法实现Python的单例模式:
可以看到虽然创建了两个对象,但两个对象的地址相同。
2、控制属性访问这类魔法
方法主要对对象的属性进行访问、定义、修改时起作用。主要有:
__getattr__(self, name): 定义当用户试图获取一个属性时的行为。
__getattribute__(self, name):定义当该类的属性被访问时的行为(先调用该方法,查看是否存在该属性,若不存在,接着去调用getattr)。
__setattr__(self, name, value):定义当一个属性被设置时的行为。
当初始化属性时如self.a=a时或修改实例属性如ins.a=1时本质时调用魔法方法self. __ setattr __ (name,values);当实例访问某个属性如ins.a本质是调用魔法方法a. __ getattr __ (name)
3、容器类操作
有一些方法可以让我们自己定义自己的容器,就像Python内置的List,Tuple,Dict等等;容器分为可变容器和不可变容器。
如果自定义一个不可变容器的话,只能定义__ len__ 和__ getitem__ ;定义一个可变容器除了不可变容器的所有魔法方法,还需要定义__ setitem__ 和__ delitem__ ;如果容器可迭代。还需要定义__ iter __。
__len__(self):返回容器的长度
__getitem__(self,key):当需要执行self[key]的方式去调用容器中的对象,调用的是该方法
__setitem__(self,key,value):当需要执行self[key] = value时,调用的是该方法
__iter__(self):当容器可以执行 for x in container:,或者使用iter(container)时,需要定义该方法
下面举一个例子,实现一个容器,该容器有List的一般功能,同时增加一些其它功能如访问第一个元素,最后一个元素,记录每个元素被访问的次数等。
这类方法的使用场景主要在你需要定义一个满足需求的容器类数据结构时会用到,比如可以尝试自定义实现树结构、链表等数据结构(在collections中均已有),或者项目中需要定制的一些容器类型。
魔法方法在Python代码中能够简化代码,提高代码可读性,在常见的Python第三方库中可以看到很多对于魔法方法的运用。
因此当前这篇文章仅是抛砖引玉,真正的使用需要在开源的优秀源码中以及自身的工程实践中不断加深理解并合适应用。
魔方方法是Python的内置方法,无需主动调用,主要目的就是为了给Python的解释器进行调用,而且每个魔方方法都有一个对应的内置函数或运算符,接下来我们来看看具体的介绍。
魔法方法就是可以给你的类增加魔力的特殊方法,如果你的对象实现(重载)了这些方法中的某一个, 那么这个方法就会在特殊的情况下被Python所调用,你可以定义自己想要的行为,而这一切都是自动发 生的,它们经常是两个下划线包围来命名的(比如 __init___ , __len__ ),Python的魔法方法是非常强大的所以了解其使用方法也变得尤为重要!
__init__ 构造器,当一个实例被创建的时候初始化的方法,但是它并不是实例化调用的第一个方法。
__new__ 才是实例化对象调用的第一个方法,它只取下cls参数,并把其他参数传给 __init___。
___new__ 很少使用,但是也有它适合的场景,尤其是当类继承自一个像元祖或者字符串这样不经常改变的类型的时候。
__call__ 让一个类的实例像函数一样被调用。
__getitem__ 定义获取容器中指定元素的行为,相当于self[key]。
__getattr__ 定义当用户试图访问一个不存在属性的时候的行为。
__setattr__ 定义当一个属性被设置的时候的行为。
__getattribute___ 定义当一个属性被访问的时候的行为。
__init__属于魔法函数的一种,让我们来看一下它的前世今生吧。后面介绍了其他的魔法函数:__ str__()、__ new__()、__ unicode__()、__ call__()、__ len__()、__repr__()等等
所谓魔法函数(Magic Methods),是Python的一种高级语法,允许你在类中自定义函数(函数名格式一般为__xx__),并绑定到类的特殊方法中。比如在类A中自定义__str__()函数,则在调用str(A())时,会自动调用__str__()函数,并返回相应的结果。在我们平时的使用中,可能经常使用__init__函数(构造函数)和__del__函数(析构函数),其实这也是魔法函数的一种。
Python中以双下划线(__xx__)开始和结束的函数(不可自己定义)为魔法函数。
调用类实例化的对象的方法时自动调用魔法函数。
在自己定义的类中,可以实现之前的内置函数。
在Python中,如果我们想实现创建类似于序列和映射的类(可以迭代以及通过[下标]返回元素),可以通过重写魔法方法 __getitem__、__setitem__、__delitem__、__len__ 方法去模拟。
__getitem__(self,key): 返回键对应的值。
__setitem__(self,key,value): 设置给定键的值
__delitem__(self,key): 删除给定键对应的元素。
__len__(): 返回元素的数量
【注释】只要实现了 __getitem__ 和 __len__ 方法,就会被认为是序列。
这些魔术方法的原理就是:当我们对类的属性item进行下标的操作时,首先会被 __getitem__()、__setitem__()、__delitem__() 拦截,从而执行我们在方法中设定的操作,如赋值,修改内容,删除内容等等。
这个方法应该以与键相关联的方式存储值,以便之后能够使用 __setitem__ 来获取。当然,这个对象可变时才需要实现这个方法。
举个栗子:
定义一副扑克牌(不包括大小王),对牌进行洗牌,然后发牌。
Output:
【注意】 :我们会发现output中,输出了: slice(1, 3, None) ,下面给出解释。
语法:
参数说明:
slice() 函数实现切片对象,主要用在切片操作函数里的参数传递。
举两个栗子来看看:
Output:
切片原理
output
(程序员必会的 hhhhh.....)
看看slice在python3.7中是怎么描述的: