python魔法函数__call__你不知道的秘密

liftword1周前 (06-07)技术文章2

视频链接
https://zhuanlan.zhihu.com/p/562586782

什么是魔法函数?

是以双下划线开头和双下划线结尾命名的特殊函数,不需要开发者调用,由Python解释器调用。

可调用对象的概念:在python中,能够使用名称加()执行的对象都是可调用对象。

很显然所有的函数都是可调用对象,那么类实例对象是调用对象吗?

实验下:


报错了,错误信息提示Student对象不是一个可调用对象。

检测一个对象是否可调用还可以使用callable函数。


返回False,也说明了Student对象不是一个可调用对象。

那么这么才能拿让类实例对象变成可调用对象呢?

只要类实现了魔法函数__call__即可,我们试下。


很明显实现了__call__之后,Student对象变成了可调用对象;

其中__call__不需要要开发者来调用,它属于特殊函数,解释器会去调用的。

为什么要将了转化成可调用对象呢?哪些场景使用?

可调用对象,让类实例对象能够像函数一样接收参数,好处是更加简洁,不需要使用 对象.方法()。

使用场景:

1.在一些验证器中使用,举个例子:

import re

class PhoneValidator():

'''DEC:手机号格式合法验证器'''

def __call__(self, *args, **kwargs):

reg = '^1(3[0-9]|4[5,7]|5[0,1,2,3,5,6,7,8,9]|6[2,5,6,7]|7[0,1,7,8]|8[0-9]|9[1,8,9])\d{8}#39;

phone = args[0]

if not re.match(reg, phone):

print("phone is validate.")

else:

print("phone is invalidate.")

phone_validator = PhoneValidator()

phone_validator("13735468254")

phone_validator("10735468254")

结果:

phone is invalidate.

phone is validate.

你可能会为那为什么不使用函数呢?类有更好的扩展性,你可能还需要做其他的事情呢?

所以我们需要的是函数但是又不仅仅只是函数。

2.在类装饰器中使用,在装饰器章节详细看下类装饰器。

'''

描述:虽然装饰器是用类实现的,但是最终用来替换原函数的对象,仍然是一个处在__call__方法里的闭包函数

'''

import time

import random

from functools import wraps

class Timer:

"""装饰器:打印函数的耗时

:param print_args:是否打印发发那个发名和参数,默认为False

"""

def __init__(self,print_args):

self.print_args = print_args

def __call__(self, func):

@wraps(func)

def decorated(*args, **kwargs):

'''

desc:jdhfksjdf

@param:args,

'''

st = time.perf_counter()

ret = func(*args, **kwargs)

if self.print_args:

print(f'"{func.__name__}",args:{args},kwargs:{kwargs}')

print("time cost:{} seconds".format(time.perf_counter()-st))

return ret

return decorated

@Timer(print_args=True)

def random_sleep():

print("random")

if __name__ == '__main__':

random_sleep()

相关文章

太好用!教你几招Python魔法方法的妙用

专注Python、AI、大数据,请关注公众号七步编程!Python是一种简单的编程语言,满足一个需求,可以有各种各样的实现方法。正是因为它可以通过各种串联满足很多复杂的逻辑,因此,对代码可读性关注度不...

11 每个程序员都应该知道的 Python 魔法方法

在 Python 中,魔法方法帮助你模拟 Python 类中内置函数的行为。这些方法有前后双下划线(__),因此也被称为魔法方法 。这些魔法方法也帮助你实现 Python 中的运算符重载。你很可能见...

Python中关于魔法方法、单例模式的知识

目录:init,del,add,str和 repr,call,单例模式,class,dict,doc,bases,mro魔法方法:定义:在特定条件下,触发方法在python里面很多以双下划线开头且结尾...

掌握Python的"魔法":特殊方法与属性完全指南

在Python的世界里,以双下划线开头和结尾的"魔法成员"(如__init__、__str__)是面向对象编程的核心。它们赋予开发者定制类行为的超能力,让自定义对象像内置类型一样优雅工...

Python 魔法方法的工作原理:实用指南(三)

以前的文章我们讲了python中对象表示、运算符等魔法方法的用法,下面我们继续深入探索容器、资源管理、性能方面的魔法方法。容器方法(类似列表、字典对象)当你需要自定义存储和检索数据的对象时,此方式可以...

Python进阶——如何正确使用魔法方法?(上)

微信搜索关注「水滴与银弹」公众号,第一时间获取优质技术干货。7年资深后端研发,用简单的方式把技术讲清楚。在做 Python 开发时,我们经常会遇到以双下划线开头和结尾的方法,例如 __init__、_...