zoukankan      html  css  js  c++  java
  • 转载---滋滋有味看完的一篇文章关于python与java夜话

    这是一个程序员的电脑硬盘,在一个叫做“学习”的目录下曾经生活着两个小程序,一个叫做Hello.java,即Java小子;另外一个叫做hello.c ,也就是C老头儿。
    
    
    
    C老头儿的命运比较悲催,程序员主人觉得C语言的指针太复杂了,内存管理太难了,实在是学不会,就放弃了,顺便把它给删除了!
    
    
    
    Java小子很怀念它,因为C老头儿虽然老派,但知识渊博,教了他不少东西。
    
    
    
    (码农翻身注:参见文章《C老头和Java小子的硬盘夜话》)
    
    
    
    这天晚上,程序员心血来潮,决定跟Python混个脸熟,于是hello.py也入住了这个目录。
    
    
    
    经过了短暂的寒暄,摸清了对方的虚实,他俩便看对方不顺眼了。
    
    
    
    他俩都明白一山不容二虎的道理,如果不能把对方赶走,就难逃被主人删除,去垃圾回收站的悲催命运。
    
    
    
    想到这一层,Python变率先发难, 它皮笑又不笑地拍拍Java的肩膀:“Java 老弟....”
    
    
    
    没想到Java立刻反击:“谁是你老弟?你得叫我Java 大哥。”
    
    
    
    Python愣了一下:“难道你不知道我是1991年出生的,比你还大4岁?”
    
    
    
    Java哼了一声:“虽然比我大,那你混得也不怎么样啊?”
    
    
    
    Python说:“10多年前我也许混得不咋地,也许不如你,可此一时彼一时,随着人工智能时代的到来,使用我的人越来越多了,不信你去看TIOBE排行榜,我的上升势头很猛烈啊。”
    
    
    
    Java不屑地说:“切,增长到现在不还是老子一个零头。”
    
    
    
    Python 被激怒了,他决定先拿Java繁琐的语法开刀,指着Java说:“看看你,一个HelloWorld都整得这么麻烦,啰里啰嗦。”
    
    
    
    public class Hello
    {
        public static void main (String[] args)
        {
            System.out.println("Hello World!");
        }
    }
    
    
    然后又指着自己说:“你看看我,多么简洁!”
    
    
    
    print("Hello World!")
    
    
    Java 默不作声,其实心里也挺羡慕。
    
    
    
    “还有我打开一个文件多简单,你行吗?”
    
    
    
    f = open("c:\tmp\Hello.java","r")
    print(f.read())
    f.close()
    
    
    
    
    提到IO,Java心中就有莫名的痛,自己的IO模块设计得那么优雅,可是人类为什么就是不喜欢用呢?
    
    
    
    他们老是说记不住到底该怎么写,看来是要改变下了。
    
    
    
    看到Java 还是默不作声,无法反击,Python很得意,发挥宜将剩勇追穷寇的精神,抄起机关枪,继续扫射:“看看我这个函数的缺省值,你有吗?”
    
    
    
    class Employee():
        def __init__(self, name  , gender="male" , maritalStatus="single" ):
            self.name          = name
            self.gender        = gender
            self.maritalStatus = maritalStatus
    (友情提示:可左右滑动)
    
    Java 一看到这段代码,立刻就来了精神:“你的self和我的this意思差不多,可是你为啥必须作为参数呢? 多丑陋啊!!还有这代码缩进,居然用空格,一不留神就出错,真不知道你到底是怎么想的。”
    
    
    
    Python 没想到Java这小子竟然从这个地方发起反击, 一时语塞。
    
    
    
    只听到Java 问道:“有人说你Python的变量都没有类型,是吗?”
    
    
    
    “胡说!我的变量怎么没有类型?我是动态语言,类型只会在运行时确定。”
    
    
    
    var = 3
    var = "hello world"
    
    
    “你看看,这个变量var 第一次赋值,类型是个整数, 第二次就变成字符串hello world了, 你小子做不到吧?”
    
    
    
    Java笑而不语。
    
    
    
    Python继续说道:“由于我的动态特性,我可以轻松地实现Duck Typing:”
    
    
    
    class Duck:  
        def help(self):  
            print( "Quaaaaaack! ")  
    class Person:  
        def help(self):  
            print( "help me!" )  
    
    def in_the_forest(x):  
        x.help()  
    
    in_the_forest(Duck())
    in_the_forest(Person())
    
    
    “看到没有,这个Duck和Person并没有实现共同的接口或者继承相同的类,但是照样可以作为参数传递给in_the_forest函数,是不是很灵活? 你应该是不行吧? 哈哈!”  Python得意洋洋。
    
    
    
    Java心里明白,这的确是个很好的特性,写起代码来非常爽快。
    
    
    
    但他也不是吃素的, 一下子就抓住了命门: “写起来很爽,读起来就不爽了,我问你,假设人类看到了in_the_forest这个函数,他知道参数x的类型是什么吗?是Person? 是Bird? 还是别的类? ”
    
    
    
    “还有,” Java继续批判,“人类想重构一下Person函数的help方法,比如改成sos(self),你的IDE能安全地重构吗?恐怕是不容易吧? 假设人肉重构改错了,你也只能在运行时发现错误了!”
    
    
    
    “动态一时爽,重构火葬场。”  Java 冷冷地补了最后一刀。
    
    
    
    由于自己是静态类型,变量类型在编译期就能确定,IDE那强大的智能感知功能,自动安全重构的功能一直是引以为傲的卖点。
    
    
    
    “怕啥,” Python假装满不在乎,“人类有单元测试做保证,再说了,我的代码紧凑得很,一行顶你十行,就是改起来也方便得多。”
    
    
    
    虽然表面满不在乎,可Python已经暗暗心惊:一不小心被这小子带坑里去了,我得想办法转移阵地。
    
    
    
    Java 开始组织防守反击: “听说过AOP没有?啊? 听说过,那你说说,你能不能实现AOP?”
    
    
    
    Python 心里偷着乐:这小子真是孤陋寡闻,总以为只有什么Spring有AOP, 岂不知对于我们动态语言来说,实现AOP那简直是易如反掌。
    
    
    
    Python故意问道:“AOP无非就是对现有代码做增强,动态地添加一些安全,日志,事务等‘切面’功能,我知道你们Java 类,一旦被装载就无法修改,那怎么去实现代码的增强呢?”
    
    
    
    Java得意地说:“我们可以在运行时生成新的类啊,让新生成的类继承老的类,或者和老的类实现同样的接口,比如ASM这样的工具,可以操作字节码去创建新的类,织入那些‘切面’代码,这种工作如此精巧,让人叹为观止。”
    
    
    
    Python说道:“哈哈,我告诉你吧, 你那是不得已而为之,我们Python 就不同了,我们是动态语言,可以在运行时对一个类进行增强:添加方法,替换方法,根本不用操作那么Low的字节码,我给你举个简单的例子:”
    
    
    
    class Order:
        def save(self):
            print ("save order")
    
    #把老的方法引用保存起来
    old_save=Order.save
    
    #定义一个新方法,该新方法调用老方法
    #并在方法前后加上了日志
    
    def save_with_logging(self):
        print ("logging start")
        old_save(self)
        print ("logging end")
    
    #把新方法赋值给Order类的save方法
    Order.save=save_with_logging
    
    #测试
    t=Order()
    t.save() 
    
    
    输出:
    
    logging start
    
    save order
    
    logging end
    
    
    
    Java看着这段代码,瞠目结舌,心惊肉跳,一个类的方法在运行时竟然可以被替换掉! 实在是吓人啊!在自己的世界中,这是想都不敢想的事情。
    
    
    
    可是这不就轻松实现了对一个类的增强吗? 也不用修改什么字节码。
    
    
    
    Python看到Java小子被镇住了,继续施压: “我们Python想实现AOP,还可以使用装饰器,Meta class等很多方式,我就不给你详细讲了。”
    
    
    
    Java心里还在想着那个被替换的函数, 看来在Python中, 函数就是一个对象,要不然怎么能被替换掉? 既然是个对象,那肯定可以作为参数传递,也可以做为返回值。 想想自己的Lambda表达式,本质上还是一个接口的实现,相当于带着镣铐在跳舞,心里不由得叹了口气。
    
    
    
    (码农翻身注:参见《Lambda表达式有何用处?》)
    
    
    
    看来我还得找出杀手锏才能彻底将这个自大的Python小子给搞定,Java心想,可是他的动态语言确实是太灵活了,对了,虚拟机! 我的虚拟机发展了这么多年,经受了业界最苛刻的考验,性能强悍,在解释执行字节码的过程中能发现那些“热点”字节码,然后编译成本地代码执行,速度极快。 并且我的垃圾回收机制也极为完善。
    
    
    
    Java把这个大杀器给抛了出来,Python的表情立刻就不对了,因为自己虚拟机的性能确实不怎么样,但是Python非常狡猾,他立刻就把话题给转移了:“现在的速度瓶颈不是CPU, 而是IO, 你知道网络和数据库这俩货有多慢吗? 相对他们的速度,我们慢一点也没关系......”   Python成功地把两个人拉到了同一个阵地中。
    
    
    
    两个家伙你来我往,整整争论了一夜,他们俩的声音越来越大,吵得隔壁的“毕业设计.docx”怒气冲冲地跑过来骂道:“到底还让不让老子睡觉了?!”
    
    
    
    两个人赶紧压低声音,继续争斗,但谁也没办法彻底占据上风,最后就觉得大家真是各有所长,只是适用范围各不相同。
    
    
    
    突然间,一道亮光照进来,把两人的眼睛刺得生疼,原来天已大亮,主人打开了这个文件夹,选中了Hello.java和hello.py ,然后做了一个奇怪的操作。
    
    
    
    Java 和Python 只觉得一阵头晕目眩,转瞬间就被拎到一个垃圾遍地的地方。
    
    
    
    只见头发蓬乱的C老头儿在一本叫做《C和指针》的电子书上坐着,目光呆滞地对他俩说:“你们好,欢迎来到回收站。看来主人又有了新欢,把你们俩也抛弃了。”
    
    如果有来生,一个人去远行,看不同的风景,感受生命的活力。。。
  • 相关阅读:
    我要好offer之 二叉树大总结
    我要好offer之 字符串相关大总结
    楼层扔鸡蛋问题[转]
    Linux System Programming 学习笔记(十一) 时间
    Linux System Programming 学习笔记(十) 信号
    Linux System Programming 学习笔记(九) 内存管理
    Linux System Programming 学习笔记(八) 文件和目录管理
    Linux System Programming 学习笔记(七) 线程
    Linux System Programming 学习笔记(六) 进程调度
    APUE 学习笔记(十一) 网络IPC:套接字
  • 原文地址:https://www.cnblogs.com/Frank99/p/9766043.html
Copyright © 2011-2022 走看看