zoukankan      html  css  js  c++  java
  • pythong 中的 __call__

    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里需要这么多“设计模式”的主要原因。一旦有了一等函数,你将不再需要大部分的这些设计模式。

  • 相关阅读:
    DIV 模拟模式窗体
    存储过程传递参数时出现类型转换错误!如:varchar转换为int时出错
    数据库改名附加
    VC++动态链接库(DLL)编程深入浅出
    JS获取各种宽度,高度解释
    IE6 中的最大最小寬度和高度 css 高度 控制(兼容版本)
    CSS浏览器兼容大总结
    js获取屏幕宽度高度
    FF下文本无法撑开容器的高度解决办法
    浏览器兼容手册(JS+CSS)
  • 原文地址:https://www.cnblogs.com/nucdy/p/6382063.html
Copyright © 2011-2022 走看看