共计 1872 个字符,预计需要花费 5 分钟才能阅读完成。
咱们明天来看一段炫技代码。它能够把任何能接管两个参数的函数定义成一个非凡的运算符。
例如,咱们晓得 Python 外面的 range
函数,起码能够接管 1 个参数,最多可能接管 3 个参数。当只有两个参数的时候,格局为 range(开始, 完结)
,从开始数字到完结数字逐次加 1,左闭右开。应用明天的办法,能够把它的写法改为 开始 | 到 | 完结
,如下图所示:
又比方,urllib.parse.urljoin
能够把域名和一个相对路径拼接起来: urljoin(域名, 相对路径)
,咱们也能够改写成如下图所示的格局:
这种炫技无余,实用有余的性能是怎么实现的呢?其实原理非常简单,只有 8 行代码:
from functools import partial
class Change(object):
def __init__(self, func):
self.func = func
def __or__(self, other):
return self.func(other)
def __ror__(self, other):
self.func = partial(self.func, other)
return self
这里就波及到一个盲点和两个真正的知识点。这个盲点就是,你可能认为 | 到 |
是一个字符,然而它是 3 个字符;你可能会把 | 拼接 |
看做一个整体,然而它实际上是 3 个局部:右边的 |
、 拼接
和左边的|
。
咱们把空格加上,就很显著了:
两个真正的知识点,就是 __or__
和__ror__
这两个魔术办法和偏函数 partial
。而Change
自身就是一个一般的类而已,__or__
和 __ror__
定义了这个类的实例在左侧遇到 |
时,右侧遇到 |
时的具体行为。
咱们一个一个来讲。首先是 __or__
。它定义了实例的右侧遇到|
时的具体行为。例如,咱们用一个简略的代码来进行测试:
class Test:
def __init__(self, num):
self.num = num
def __or__(self, other):
print(f'我左边有一个货色,它是:{other}')
x = Test(100)
x | 55
运行成果如下图所示:
但如果你把竖线放在右边,他就会报错,如下图所示:
而 __ror__
就是用来定义 |
在实例右边的时候,它的行为:
所以,咱们最开始的例子中,2 | 到 | 10
,实际上应该了解为:
到
是Change(range)
返回的实例2 | 到
生成一个两头对象,咱们假如它是x
x | 10
生成后果
在咱们演示的例子中,2 | 到
首先进入了 Change
类的 __ror__
办法中:
def __ror__(self, other):
self.func = partial(self.func, other)
return self
其中,一开始的 self.func
就是咱们在初始化实例 Change(range)
时传入的参数 range
。所以partial(self.func, other)
等价于partial(range, 2)
。简略来说,应用偏函数,能够给一个真正的函数传一部分参数,过一会再补剩下的参数。
可能大家在日常的开发者,很少会让一个实例办法返回 self
。也就是说,1 | 到
返回的,仍然是 Change
类的一个实例,咱们简称它为 x
。这个实例的属性self.func
的值是partial(range, 2)
。
接下来,x | 10
,调用的是 __or__
办法,于是,此时执行的是 partial(range, 2)(10)
。偏函数的参数补全了,于是它外面的range
真正运行了起来,成为了range(2, 10)
。
至此,这个 Change
类咱们就解析透了。大家晓得,在 Python 外面,魔术办法是有很多的,如果你不想用|
,你还能够用其它的,例如:
或者:
或者:
同时,这个 Change
类,你甚至能够间接当做装璜器来应用。任何可能接管两个参数的函数,都能应用这个装璜器。例如:
最初总结一下。大家都晓得,我是十分拥护在工作代码中炫技的,因为炫技的写法很难读,很难保护。明天这个炫技的办法,尽管我也不举荐大家用在工作中,然而它短短 8 行代码外面,蕴含了很多个知识点,这就值得大家玩一玩了。
以上就是本次分享的所有内容,如果你感觉文章还不错,欢送关注公众号:Python 编程学习圈,每日干货分享,发送“J”还可支付大量学习材料。或是返回编程学习网,理解更多编程技术常识。