Python 最吸引你的地方是什么?
整洁的代码缩进格式?丰富的第三方包?更高的开发效率?还是良好的跨平台性?
这些特性都不足以说明 Python 的优点,最吸引人的应该是动态性所带来的灵活与便利性。
你可能听过说一个词叫做「鸭子类型」,所谓鸭子类型就是只要它走路像鸭子,叫起来像鸭子,那么你就可以认为它是鸭子。
而 Python 就有这种魔力使得任何东西都可以是鸭子,这种魔力就源自于语言的动态性, Python 提供了很多魔术方法,使得鸡可以像鸭子一样游泳
所谓魔术方法就是由 Python 内部定义,具有特殊作用的方法,这些方法有一个共同特征,以双下划线开始并以双下划线结尾,比如对象的初始化方法 __init__
,是最常用的一个魔术方法(不少初学者以为只有一个下划线,在这栽了跟头)
如何使用这些魔术方法呢?
先来看一个例子
我们都知道数字可以相加,字符串也可以相加
>>> 1+2
3
>>> "hello"+" Python"
'hello Python'
列表也可以相加
>>> [1,2,3] + [4,5,6]
[1, 2, 3, 4, 5, 6]
那么两个对象(这里特指类的实例对象)可不可以相加呢?
class Point:
def __init__(self, x, y):
self.x = x
self.y = y
def __repr__(self):
return "Point({}, {})".format(self.x, self.y)
>>> (Point(1, 2) + Point(3, 4))
Traceback (most recent call last):
File "", line 1, in
TypeError: unsupported operand type(s) for +: 'Point' and 'Point'
>>>
上面用 Point 类表示坐标系中的一个点,x,y 分别代表横轴和纵轴,两个点相加时报错了,错误日志告诉我们,对于 Point 类不支持 「+」操作。
但如果你实现了魔术方法 __add__
就可以支持加操作了
class Point:
...
def __add__(self, other):
assert isinstance(other, Point)
return Point(self.x + other.x, self.y + other.y)
再来运行:
>>> Point(1, 2) + Point(3, 4)
Point(4, 6)
再举一个例子
我们知道类的属性一般都是用点操作获取属性,例如p.x,p.y,而访问字典对应的key值都是通过 p[‘x’] 或者 p.get(“x”) 来访问的,那字典可不可以用 “.” 的方式获取呢?
>>> d = {"a":"b"}
>>> d.a
Traceback (most recent call last):
File "", line 1, in
AttributeError: 'dict' object has no attribute 'a'
显然,默认情况下是不允许通过“.”的方式获取的,但是如果你实现了魔术方法__getattr__
就可以使用点的方式获取了。
我们自定义一个类,继承 dict,再实现 __getattr__方法就可以用“.”操作了,当属性使用 a.b 的方式访问时,就会调用 __getattr__
>>> class MyDict(dict):
... def __getattr__(self, item):
... return self.get(item)
...
>>> d = MyDict(a="b")
>>> d
{'a': 'b'}
>>> d['a']
'b'
>>> d.a
'b'
如果你熟悉 Django 中 Template 语法的话,你现在应该知道为什么字典对象可以使用“.”操作获取里面的元素。
当然,魔术方法远不止这两个,全部加起来有近百来个
关于实例构建与初始化的,比如 __new__,__init__
关于属性访问控制:__getattr__,__setattr__
描述符相关的:__get__, __set__
关于操作容器的: __getitem__,__setitem__
关于上下文管理的:__enter__,__exit__
比较运算符:__cmp__,__eq__,__lt__,__gt__
算术运算符:__add__,__sub__,__mul__,__div__
回复 「magic」可获取一份完整的魔术方法介绍文档。你是使用Python过程,使用过哪些魔术方法来做一些特殊的黑科技操作呢?欢迎留言
周一赠书《年前福利,送书10本》中奖结果出来啦,恭喜以下同学:
@fly swallow
@wowking
@动感光波
@Michael
@李大侠@Mysoul@M-in @yanzu @叶知秋@玉观音
请以上同学尽快微信私信我,把你喜欢的书和联系地址发给我,2天内没发的将取消资格哦,快递要放假了
推荐阅读:
学Python,关注Python之禅