转载---滋滋有味看完的一篇文章关于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和指针》的电子书上坐着,目光呆滞地对他俩说:“你们好,欢迎来到回收站。看来主人又有了新欢,把你们俩也抛弃了。”
转载---滋滋有味看完的一篇文章关于python与java夜话的更多相关文章
- Python3入门系列之-----看完这一篇文章我终于学会了类
前言 类顾名思义,就是一类事物.或者叫做实例,它用来描述具有共同特征的一类事物.我们在Python中声明类的关键词是class,类还有功能和属性,属性就是这类事物的特征,而功能就是它能做什么,也是就是 ...
- 一篇文章掌握 Python 内置 zip() 的全部内容
一篇文章掌握 Python 内置 zip() 的全部内容 zip() 是 Python 中最好用的内置类型之一,它可以接收多个可迭代对象参数,再返回一个迭代器,可以把不同可迭代对象的元素组合起来. 我 ...
- 测试框架 Mocha 实例教程(转载:来自阮一峰的一篇文章)
Mocha(发音"摩卡")诞生于2011年,是现在最流行的JavaScript测试框架之一,在浏览器和Node环境都可以使用. 所谓"测试框架",就是运行测试的 ...
- 一篇文章彻底搞懂Java的大Class到底是什么
作者在之前工作中,面试过很多求职者,发现有很多面试者对Java的 Class 搞不明白,理解的不到位,一知半解,一到用的时候,就不太会用. 因为自己本身以前刚学安卓的时候,甚至做安卓2,3年后,也是对 ...
- 一篇文章带你了解Java OOP思想
Java OOP 思想深度刨析 Java面向对象编程 面向对象编程简称OOP(Object--对象.Oriendted--导向的.Programming--程序设计) 面向对象通俗来讲,就是指使用丰富 ...
- 一篇文章 图解Python 玩转Python
0 Python 解释器:1.Python数据结构:2.变量与运算符3 Python 流程控制 4 Python 文件处理5 python 输入输出6 Python 异常7 Python 函数和模块8 ...
- IEnumerator<TItem>和IEnumerator Java 抽象类和普通类、接口的区别——看完你就顿悟了
IEnumerable 其原型至少可以说有15年历史,或者更长,它是通过 IEnumerator 来定义的,而后者中使用装箱的 object 方式来定义,也就是弱类型的.弱类型不但会有性能问题,最主要 ...
- 面试问烂的 MySQL 查询优化,看完屌打面试官!
Java技术栈 ,一般把连接数设置得大一些). 并发量:同一时刻数据库服务器处理的请求数量 3.超高的 CPU使用率:CPU资源耗尽出现宕机. 4.磁盘 IO:磁盘 IO性能突然下降.大量消耗磁盘性能 ...
- 一篇文章弄懂 Java 反射的使用
说到Java反射,必须先把 Java 的字节码搞明白了,也就是 Class , 大 Class 在之前的文章中,我们知道了Java的大Class就是类的字节码,就是一个普通的类,里面保存的是类的信息, ...
随机推荐
- Linux mount BSD disk partition
Linux mount BSD disk partition 来源 https://www.cnblogs.com/jhcelue/p/6858159.html 假设须要从第二块硬盘复制文件.该硬盘格 ...
- MT【296】必要性探路
已知$a,b\in R.f(x)=e^x-ax+b$,若$f(x)\ge1$恒成立,则$\dfrac{b-a}{a}$的取值范围_____ 提示:答案:$[-1,\infty)$取$x=0,b\ge0 ...
- Nagios故障 CHECK_NRPE: Socket timeout after 10 seconds.
Nagios 的警报信息如下,意思是 nrpe 进程执行某些脚本超过了 10 秒钟,就会发警报 CHECK_NRPE: Socket timeout after 10 seconds 修改 comma ...
- 【arc073e】Ball Coloring(线段树,贪心)
[arc073e]Ball Coloring(线段树,贪心) 题面 AtCoder 洛谷 题解 大型翻车现场,菊队完美压中男神的模拟题 首先钦定全局最小值为红色,剩下的袋子按照其中较大值排序. 枚举前 ...
- 【LOJ#6029】市场(线段树)
[LOJ#6029]市场(线段树) 题面 LOJ 题解 看着就是一个需要势能分析的线段树. 不难发现就是把第二个整除操作化为减法. 考虑一下什么时候整除操作才能变成减法. 假设两个数为\(a,b\). ...
- ⌈洛谷1312⌋⌈NOIP提高组2011⌋Mayan游戏【搜索】
感想 真的,感觉这道题目好坑爹,我这个蒟蒻调了好几个世纪才调出来. 重构代码千万遍,依旧只有-1输出. 正解 非常明显的一道搜索题目. 每一次记录上一级的状态,这样实现比较不容易出错. 然后考虑剪枝: ...
- BUG关闭原因
已解决:缺陷已经修复. 重复缺陷:是指在系统里相同原因的缺陷已经被其他人报告.在此缺陷被作为重复缺陷返回时,先不要立即取消.必须等到核查修复后,才在系统里取消.这是因为有些缺陷被误认为是重复缺陷,实际 ...
- luogu3263/bzoj4002 有意义的字符串 (数学+矩阵快速幂)
首先我们发现$\frac{b+\sqrt{d}}{2}$这个形式好像一元二次方程的求根公式啊(???反正我发现不了) 然后我们又想到虽然这个东西不好求但是$(\frac{b-\sqrt{d}}{2}) ...
- Codeforces Round #487 (Div. 2) C - A Mist of Florescence
C - A Mist of Florescence 把50*50的矩形拆成4块 #include<bits/stdc++.h> using namespace std; ],b[]; ][ ...
- 我们如何用Go来处理每分钟100万复杂请求的场景
在Malwarebytes我们经历了显著的增长,自从我一年前加入了硅谷的公司,一个主要的职责成了设计架构和开发一些系统来支持一个快速增长的信息安全公司和所有需要的设施来支持一个每天百万用户使用的产品. ...