__call__
创新互联公司长期为上千多家客户提供的网站建设服务,团队从业经验10年,关注不同地域、不同群体,并针对不同对象提供差异化的产品和服务;打造开放共赢平台,与合作伙伴共同营造健康的互联网生态环境。为鸡泽企业提供专业的成都网站设计、网站建设,鸡泽网站改版等技术服务。拥有十多年丰富建站经验和众多成功案例,为您定制开发。
在Python中,函数其实是一个对象:
f = abs
f.__name__
'abs'
f(-123)
由于 f 可以被调用,所以,f 被称为可调用对象。
所有的函数都是可调用对象。
一个类实例也可以变成一个可调用对象,只需要实现一个特殊方法__call__()。
我们把 Person 类变成一个可调用对象:
class Person(object):
def __init__(self, name, gender):
self.name = name
self.gender = gender
def __call__(self, friend):
print 'My name is %s...' % self.name
print 'My friend is %s...' % friend
现在可以对 Person 实例直接调用:
p = Person('Bob', 'male')
p('Tim')
My name is Bob...
My friend is Tim...
单看 p('Tim') 你无法确定 p 是一个函数还是一个类实例,所以,在Python中,函数也是对象,对象和函数的区别并不显著。
任务
改进一下前面定义的斐波那契数列:
class Fib(object):
???
请加一个__call__方法,让调用更简单:
f = Fib()
print f(10)
[0, 1, 1, 2, 3, 5, 8, 13, 21, 34]
1:
简单的函数演示:
这个enumerate 函数挺有意思,用一次就爱不释手,可以自己去敲敲代码感受一下。
2:上面仅仅是简单的一个展示已经存在的书籍名称,加入我新增了一本书,新增完成之后,我需要再show一下目前我有那些书呢?
如果没有函数之前,我们肯定需要再次执行一遍所有有关print的代码,但是函数的功能就是让我们减少重复冗余的代码,只要再次调用show_book()即可。
再举一个简单的例子,在一个函数内调用另外一个函数,并传递参数
如果单纯从命 名看:
1、类使是用的大驼峰,所以类是这样的:Document()
2、函数名:全部小写
Python函数调用的特点是。函数的多变性。在python中,参数通过赋值传递给了函数(也就是说,就像我们所学过的,使用对象引用),在python中,调用者以及函数通过引用共享对象,但是改变传递的可变对象可以改变调用者共享的那个对象。
好像没有特别的叫法吧,也没注意手册上有什么特别的叫法,至于区别,举个例子你就清楚了,如下:
假如有个列表aa=[1,4,3,5],对这个列表用sort()进行排序,如果第一种方式aa.sort()后aa=[1,3,4,5];
而第二种方式sort(aa)排序后虽然得到了新列表[1,3,4,5],但是aa还是=[1,4,3,5]。
也就是说第一种方式会改变原列表,而第二种不会改变,只是得到了一个新的副本。
GOT IT?!^^
补充一下,如果非要说叫法上的区别的话,第一种叫做方法调用,第二种叫做函数调用。至于方法和函数的些微区别,方法是基于对象的,函数是基于本身的。如果再详细……方法一般不可以单独使用,因为大部分方法是基于对象的,调用也必须基于对象,像上面第一种;而函数则可以单独使用,你可以理解成它是数据系统本身的,而不是对象专有的。
PS:至于为什么我换了用sort()而没有用LZ给的例子函数,是因为..…^o^……LZ第一种方式和第二种方式写的都不是一个函数……
已有字符串形式的函数名称,那么如何调用这个函数呢?
通过调用内置函数locals()和globals()返回的字典对象,就可以可以获得名称与对象的映射关系。其中,locals()仅在全局范围内调用时可以获得函数对象。 我们来看以下的例子。
需要注意的是,使用上述方法通过字符串调用函数时,为了系统的安全,防止执行任意函数,需要对函数名做一些处理,也就是使用统一的前缀为这些函数命名。例如在上述例子中,使用前缀cmd_+函数名的形式定义函数(cmd_help,cmd_sum)。
在传入函数名字符串时,只传入函数名的后半部分(如"help","sum"),由程序添加前缀后组成完整的函数名,再调用该函数。
对于类的成员函数,则可以使用getattr()获得类成员函数。
上述代码通过字符串调用了类成员函数,与前一段代码执行的结果相同。
此外,还可以使用字典将字符串与函数对应起来调用,缺点就是每增加一个函数需要相应在字典对象中添加相应的键值,增加代码维护工作量。
以上代码在Python 3.6以上运行通过。