我们用 hasattr() 函数判断指定属性(或方法)是否存在,但到底是属性还是方法,则需要进一步判断它是否可调用。程序可通过判断该属性(或方法)是否包含 __call__ 属性来确定它是否可调用。
例如如下程序:
class User:
def __init__(self, name, passwd):
self.name = name
self.passwd = passwd
def validLogin (self):
print('验证%s的登录' % self.name)
u = User('crazyit', 'leegang')
# 判断u.name是否包含__call__方法,即判断是否可调用
print(hasattr(u.name, '__call__')) # False
# 判断u.passwd是否包含__call__方法,即判断是否可调用
print(hasattr(u.passwd, '__call__')) # False
# 判断u.validLogin是否包含__call__方法,即判断是否可调用
print(hasattr(u.validLogin, '__call__')) # True
上面程序中的粗体代码分别判断User对象的name、passwd、validLogin是否包含__call__方法。如果包含这个方法,则表示可调用,否则表示不可调用。
从上述程序的输出不难看出,对于name和passwd这两个属性,由于不可调用,所以程序在判断是否包含__call__方法时输出False;对于validLogin方法,由于是callable,所以程序判断是否包含__call__方法时输出True。
事实上,一个函数(甚至是一个对象)执行的关键在于__call__()方法。实际上 x(arg1, arg2,...) 只是 x.__call__(arg1, arg2, ...) 的一个快捷方式,所以我们甚至可以在自定义类中添加一个 __call__ 方法,让该类的实例也变成了可调用的。例如下面的代码:
# 定义Role类
class Role:
def __init__ (self, name):
self.name = name
# 定义__call__方法
def __call__(self):
print('执行Role对象')
r = Role('管理员')
# 直接调用Role对象,就是调用该对象的__call__方法
r()
上面程序的最后一行代码使用函数调用语法来调用对象,这看起来可能不对,但是由于Role类提供了__call__方法,所以调用对象的本质是执行对象的__call__方法。运行上面的代码,你会看到如下输出:
执行Role对象
对于程序中的函数,同样既可使用函数的语法来调用它,也可把函数当成对象,调用它的 __call__ 方法。例如如下示例代码:
def foo ():
print('--foo函数--')
# 下面示范了2种方式调用foo()函数
foo()
foo.__call__()
本文为原创文章,版权归知行编程网所有,欢迎分享本文,转载请保留出处!
你可能也喜欢
- ♥ Python f-string字符串格式化简介10/21
- ♥ 如何才能学好Python|花钱都买不到的秘诀03/02
- ♥ python unittest单元测试的过程12/22
- ♥ Python中的下划线是什么意思10/03
- ♥ 如何关闭 python.exe11/13
- ♥ python中属性函数的作用是什么?10/17
内容反馈