python __call__ (可调用对象)

__call__

Python中有一个有趣的语法,只要定义类型的时候,实现__call__函数,这个类型就成为可调用的。

换句话说,我们可以把这个类型的对象当作函数来使用,相当于重载了括号运算符。

例如,现在我们要计算重力环境下的自然落体位移。我们知道Sy=(gt**2)/2,那么,我们可以建立一个函数:

def g_dpm(t):
return (9.8*t**2)/2

我们都知道,地球表面的重力加速度约等于9.8m/s**2,这个函数实在没什么技术含量。

慢,头儿说了,我要算的是火星啊¥%#!

呃……你能说人家无理取闹么?EA的FIFA足球里,我还见过微重力模式的球场,总之,在计算机程序里,很多超现实的需求都有可能。

恩,最简单的办法当然是:

def mar_g_dpm(t):
return (3.92*t**2)/2 #火星表面的重力加速度约等于地球表面的2/5

不过,你真的能保证下次那个可爱的策划不会再设计一个金星场景?或者木星?或者该死的大魔导师行会开始出售新的魔法卷轴——重力操控?

当然,我们可以这样设计这个函数:

def g_dpm(g, t):
return (g*t**2)/2

但是g相对于t,是一个稳定得多的数量,基本上,在一次相关运算中,g可以当作常量。那么,一个可调用对象也许更适合。下面定义这样一个类型:

class g_dpm(object):
def __init__(self, g):
self.g = g
def __call__(self, t):
return (self.g*t**2)/2

计算地球场景的时候,我们就可以令e_dpm = g_dpm(9.8),s = e_dpm(t)。同样的方式,可以很容易的生成其他重力环境下的自由落地公式。

另外:引入:王根

为什么说面向对象编程和函数式编程都有问题

http://www.vaikan.com/whats-wrong-with-oop-and-fp/

也许你会反驳,在Python和Scala语言里,函数也是对象。在Python中,所有的含有一个叫做__call__的方法的对象其实都是函数。

类似的,在Scala语言里,函数是拥有一个叫做apply方法的对象。但是,经过认真的思考后,你会发现,它混淆了源祖和衍生物的概念。

函数是源祖,包含函数的对象实际是衍生物。__call__apply它们自身首先就是要定义的所谓“函数对象”。

Python和Scala实际上是绑架了函数,把它们监禁在“对象”里,然后打上“__call__” 和 “apply” 标签,把它们称作“方法”。

当然,如果你把一个函数封装到对象里,你可以像使用一个函数那样使用对象,但这并不意味着你可以说”函数也是对象“

大多数的面向对象语言里都缺乏正确的实现一等(first-class)函数的机制。Java语言是一个极致,它完全不允许将函数当作数据来传递。

你可以将全部的函数都封装进对象,然后称它们为“方法”,但就像我说的,这是绑架。

缺乏一等函数是为什么Java里需要这么多“设计模式”的主要原因。一旦有了一等函数,你将不再需要大部分的这些设计模式。

pythong 中的 __call__的更多相关文章

  1. python中的__call__方法

    在Python中,函数其实是一个对象: >>> f = abs >>> f.__name__ 'abs' >>> f(-) 由于 f 可以被调用, ...

  2. python中的__call__()函数

    __call__ 在Python中,函数其实是一个对象: >>> f = abs >>> f.__name__ 'abs' >>> f(-123) ...

  3. python中的__call__

    如果python中的一个类定义了 __call__ 方法,那么这个类它的实例就可以作为函数调用,也就是实现了 () 运算符,即可调用对象协议 下面是一个简单的例子: class TmpTest: de ...

  4. python中的__call__函数

    简单实例: class TmpTest: def __init__(self, x, y): self.x = x self.y = y def __call__(self, x, y): self. ...

  5. pythong中字符串strip的用法

    strip的用法是去除字符串中前后两端的xx字符,xx是一个字符数组,并不是去掉“”中的字符串, 数组中包含的字符都要在字符串中去除.默认去掉空格,lstrip则是去掉左边的,rstrip是右边的 见 ...

  6. 11-类中的__call__函数

    __call__是一个很神奇的特性,只要某个类型中有__call__方法,,我们可以把这个类型的对象当作函数来使用. 举例: >>>class Reader(): def __ini ...

  7. 类中的__call__()

    class A: def __call__(self, *args, **kwargs): print('执行了call方法') def call(self): print('执行call方法') c ...

  8. pythong中的全局变量的调用和嵌套函数中变量的使用

    全局变量调用:想要在自定义的函数中使用全局变量,就得要在函数用关键字global声明,然后就可以对全局变量进行修改.嵌套函数中的变量的调用:要在嵌套的变量中,使用nonlocal的声明'''num = ...

  9. Python中的__init__()和__call__()函数

    Python中的__init__()和__call__()函数 在Python的class中有一些函数往往具有特殊的意义.__init__()和__call__()就是class很有用的两类特殊的函数 ...

随机推荐

  1. 对话框上动态控件的创建、在Picture Control控件上显示图片

    1  MFC对话框之上的动态控件的创建 对话框上的控件是MFC类的一个具体对象. 当在对话框之上使用静态控件时,可以根据类向导来为每个控件添加消息.响应函数以及变量. 当需要在对话框中动态的创建某个控 ...

  2. [转载]Unity3D游戏引擎最详尽基础教程

    原文地址:Unity3D游戏引擎最详尽基础教程作者:ShangShang 我一直向所有想做游戏的朋友推荐Unity3D,为什么呢?首先是因为专业,Unity3D非常强大,用它创建一个类似MiniGor ...

  3. python文本 字符串逐字符反转以及逐单词反转

    python文本 字符串逐字符反转以及逐单词反转 场景: 字符串逐字符反转以及逐单词反转 首先来看字符串逐字符反转,由于python提供了非常有用的切片,所以只需要一句就可以搞定了 >>& ...

  4. Uber分布式追踪系统Jaeger使用介绍和案例

    原文:Uber分布式追踪系统Jaeger使用介绍和案例[PHP Hprose Go] 前言   随着公司的发展,业务不断增加,模块不断拆分,系统间业务调用变得越复杂,对定位线上故障带来很大困难.整个调 ...

  5. Spring Data Jpa 查询返回自定义对象

    转载请注明出处:http://www.wangyongkui.com/java-jpa-query. 今天使用Jpa遇到一个问题,发现查询多个字段时返回对象不能自动转换成自定义对象.代码如下: //U ...

  6. Javascript数组操作及索引

    1:清空数组最高效的做法 parentThis.PaperQuestionStrategiesList.length = 0;   2:push and pop parentThis.PaperQue ...

  7. mybatis查询时间段sql语句

    转载自:http://blog.csdn.net/zl544434558/article/details/24428307?utm_source=tuicool&utm_medium=refe ...

  8. iOS:步进UIStepper、滑动块UISlider、开关UISwitch的基本使用

    步进UIStepper.滑动块UISlider:当它们作为事件,被触发时,它们的值会发生改变.正因为如此,触发该事件时,可以一张一张翻阅浏览图片,,,, 步进UIStepper: @property( ...

  9. typedef的用法和相关问题

    用了C和C++这么久,今天才仔细研究了下typedef的用法,真的是惭愧啊,不过基础都是不断巩固的啊. typedef 在计算机编程语言中用来为复杂的声明定义简单的别名,与宏定义有些差异.它本身是一种 ...

  10. Apache PHP Mysql 开发环境快速配置

    学习PHP开发要配置各种环境,一般会用到apache作为服务器.Mysql数据库.如何快速的配置环境成为困扰大家的烦恼,之前自己也配过,比较繁琐. 最新发现一款集成安装软件“phpStudy”.真可谓 ...