热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Java帝国是否能成功渗透Python领域?或许你应该关注这个问题的答案!

01:引子Java帝国已经成立20多年,经过历代国王的励精图治,可以说是地大物博,码农众多。可是国王依然不满足,整天想着如何继续开拓疆土,这一天晚上他又把几个重臣招来商议了。IO大

01:引子

Java 帝国已经成立20多年,经过历代国王的励精图治,可以说是地大物博,码农众多。

可是国王依然不满足,整天想着如何继续开拓疆土, 这一天晚上他又把几个重臣招来商议了。

IO大臣说:“陛下,现在天下大势初定,我Java帝国已经占据了后端开发,大数据,Android开发等重要地盘,再想拓展殊为不易!”

“是啊, 前端被Javascript所盘踞,我们很难渗透啊。” 线程大臣补充。

国王点点头,这话不错,Javascript一统前端,Flash消失了,Applet不见了。想到Applet,国王就一阵心痛,当时Java是靠了Applet才引起码农的关注,一炮走红,后来怎么就不行了呢?

“那人工智能呢?” 国王狠狠地问道。

“陛下明鉴,人工智能底层都是C/C++的地盘,应用层被Python等所侵占。 ” JDBC大臣回答。

“云计算呢?”

“似乎是Go语言的地盘。”

“嘶——” 国王觉得有点牙疼。

IO大臣赶紧为君主分忧:“陛下,现在群雄涿鹿,八分天下,边境战火连年不息,陛下不仅维持住祖宗的基业,还有不小的扩展,已经是一代圣主了,不过多年征战,民力维艰,老臣有一计,也许能换来奇效。”

“爱卿快讲!”

“老臣以为不战而屈人之兵才是上策,作为世界最强之王国,不仅要武力上震慑群雄,更要输出我堂堂Java帝国之文化和价值观。”

“什么文化和价值观?”

“首先我们要大肆宣扬静态语言的种种好处,比如编译期检查发现错误,代码适合阅读和维护,适合大规模团队合作,口号我都想好了,就叫‘动态一时爽,重构火葬场!’ ”

“嗯,这口号不错!” 国王赞许,“爱卿真是老成谋国。”

“可是有些语言也是静态的啊!你怎么宣传?” 老对头线程大臣发难。

“陛下您想想,我们有很多宝贝,” IO大臣根本不理线程大臣, 继续侃侃而谈:“ 比如IoC、AOP、反射、动态代理、泛型、注解、JDBC、JMS......还有我们引以为豪的JVM。这些东西,那些国家可不一定有,我们派出老师,把这些东西灌输给他们的臣民,让他们体会到Java的种种好处,慢慢地就把他们给同化了!到时候他们的码农自然而然就会加入我Java帝国。”

“陛下万万不可,不同的语言有不同的特点,我们的文化别人是接受不了的,到时候只会引起群雄耻笑。” 线程大臣觉得IO大臣脑洞大开,简直是胡闹,非要误国不可。

“可以一试嘛!” 国王牙不疼了,“此事由IO大臣全权负责,一年后看效果。”

 

02:泛型

作为被派往Python王国的老师,吉森带着IO大臣的重托,风尘仆仆,终于来到了Python 王国。

IO大臣在挑选人选的时候,有个重要的原则:是Java的死忠粉丝,最好是对其他语言根本不了解,省得思想被污染。 这吉森就是其中的佼佼者。

吉森先找到一个地方安顿下来,然后边四处闲逛, 他惊奇地发现,这里类方法中的self满天飞, 还有强制代码缩进,果然和我大Java不同,颇有异域风情。

前面是个茶馆,人声鼎沸, 吉森走了进去,看看能不能牛刀小试,宣扬一下Java的文化。

“小二,我观察了半天,你们这里怎么没有讨论泛型啊?” 吉森拉住上茶的店小二。

“泛型? 那是什么东西? ” 小二大惑不解。

“你肯定是个外乡人,不是来自C++就是Java,我说得没错吧?” 旁边不知道什么时候来了一个老头儿。

“老先生眼光不错,我确实从Java王国来,我很纳闷,这里怎么没有泛型啊,据我所知,泛型可以在编译期做类型检查,码农们在写代码的时候也不需要做类型的转换,非常好用的啊。” 吉森开始灌输Java的种种好处。


List files = new ArrayList();
String file = files.get(0); //不必做强制类型转换
files.add(new File(.....)) ; // 编译错误

“外乡人,我们Python中的变量是不需要声明类型的,不会做编译期类型检查,只有在运行时才会检查这个变量到底是什么类型,能否调用它的方法,你说,我们要泛型有什么用?”

吉森大惊,卧槽,这IO大臣怎么没告诉自己啊, 人家根本就没这个需求!

想想我大Java费了那么大劲儿去实现泛型,没想到在Python这里完全无用武之地, 还输出什么文化! 传什么教!

 

03:反射

吉森觉得有点被IO大臣坑了! 不过多年的历练只是让他稍微慌乱,他马上稳住神,转移话题: “先生所言极是,晚生还有一个问题,这Python能支持反射吗? ”

在Java王国,人们经常通过反射的方式来获取一个类的属性、方法,然后根据一个字符串的名称来调用某个类的方法。

比如有个url : /user?action=Login

系统根据约定解析它,确定类是User, 方法是Login。然后就可以把User对象创建起来,通过反射调用Login 方法。


public class User{
public void login(...){
......
}
}

“哈哈哈,你这个外乡人啊,你知道为什么我们Python是动态语言吗? 我们Python的反射功能不知道比你们Java强到哪里去了!来来来,我给你看个例子。”


class User:
def login(self):
print("this is login")

“现在我打印他所有的方法:”


methods = [x for x, y in User.__dict__.items() if type(y) == FunctionType]
print(methods) #输出 ['login']

“接下来我通过反射调用Login方法, 老夫很久没写代码了,可能不太严谨,你明白意思就行。”


url = "/user?action=login"
#从url解析得到类和action,代码略
clz = "User"
action = "login"
#根据名称获得User对象和方法
user = globals()[clz]()
func = getattr(user,action) #获取login方法
func() #输出This is login

吉森看到这么寥寥几行代码,就实现了基本的反射, 真是灵活啊,这Python真是不错,他都有点羡慕了。

 

04:动态代理

不, 我肩负IO大臣的重托, 我是来传教的,不能让这老头儿给洗脑了!

吉森想起来了一个大杀器:动态代理,这可是Java的一个非常基础的技术,可以在运行时实现类和方法的增强,比如在调用业务方法的前后加上事务管理,日志管理等功能,没有动态代理,AOP就别想了。

吉森说道:“老先生,Python怎么去实现动态代理啊?”

老头儿微微一笑:“Java Class有个缺点, 一旦被装入Java虚拟机,就没法修改了,想对他做增强,只能修改字节码创建新的类,对老的类做封装,就是代理。但是Python是个动态语言,在运行时就可以修改啊,比如我可以动态地给User类增加一个新的属性,这一点你的Java做不到吧?”


setattr(User,"name",'andy')
print(user.name) #andy

吉森看得目瞪口呆,这真是颠覆了自己从小养成的世界观:一个类在运行期是不能改变的,更不可能去增加什么属性。

老头儿又接着说:“你看看这个User类,和Proxy类,每次调用Login方法的时候,我都可以动态地创建一个新的方法出来,在这个新的方法中,就可以做各种手脚了。”


class User:
def login(self):
print('user login')
def logout(self):
print('user logout')
class Proxy:
def __init__(self, target):
self.target = target
def __getattribute__(self, name):
target = object.__getattribute__(self, "target")
attr = object.__getattribute__(target, name)
if name == 'login' :
def newFunc(*args, **kwargs):
print ("login start")
result = attr(*args, **kwargs)
print( "login end")
return result
return newFunc
else :
return attr
u = User()
p = Proxy(u)
p.login() #实际上调用的是动态创建的方法
p.logout() #调用的是原来的方法

“你那个Proxy中的__getattribute__是什么东西啊? ” 吉森看到魔法都在这里,不由得发问。

“每当你去调用一个方法(如login/logout),或者访问一个字段的时候,Python都会通过__getattribute__先找到这个方法或者字段,然后才是真正的调用。”

“奥,原来如此,你通过__getattribute__做了手脚,如果名称是Login,就创建新的方法,在新的方法中除了调用老方法之外,还输出了日志。”

“不错,孺子可教!”

吉森现在是真心佩服动态语言了,在Java中必须得在运行时通过操纵字节码来增强,字节码啊,那可不是一般人能玩的。这Python居然在源码级别就把功能给增强了!

05:锦囊妙计

吉森有点怀疑自己此次Python王国之行的效果了,这可如何是好? 怎么回去向IO大臣复命? 当初可是立下军令状的!

他突然想起临行前,IO大臣曾经送给自己三个锦囊,嘱咐自己只有到了最危急的时刻才能打开,现在不开,更待何时?

往怀中一摸,就发现锦囊只剩下了两个,丢了一个,这回去估计要杀头, 管不了那么多了, 吉森迅速掏出一个,只见上面写着一段话:GIL(全局解释锁),GIL是Python的命门,这把超级大锁只允许一个线程获得Python解释器的控制权, 简单来说,同一时刻,只有一个线程能运行!

没想到老头儿淡淡一笑:“Python确实有GIL,可是这程序的瓶颈啊,它不在CPU, 而在于IO,就是用户的输入,数据库的查许,网络的访问,线程等到有IO操作的时候,放弃GIL这个超级大锁,让别的线程去执行就是了。再说了,你真想利用多核的时候可以用多个进程啊!”

第一个锦囊妙计被轻松化解, 吉森赶紧掏出第二个,上面几个字:“动态一时爽,重构火葬场。”

“哈哈哈,”老头儿狡黠地笑了起来:“这都是不了解情况的外人的误解,听说过Quora没有?奥,上不了是吧!这Quora就是Python写的,人家那测试用例写得非常充分,重构也不怕! 所以啊关键是测试用例!”

第二个妙计又被化解, 吉森彻底没辙了。

06:真相大白

看到吉森的神色变化,老头儿开始表明身份:“实不相瞒,老夫乃是Python国王的特使,我们的探子早就听说你们Java那什么破老师计划了,你一进入我国,就被盯上了,国王特地派我来,看看能不能说服你,留在我国。”

吉森想想,回去也无法交差,这Python似乎还不错,进退两难之际,不妨先妥协,以图将来,于是点点头答应了。

一年以后, IO大臣开始盘点老师计划,发现回来复命的寥寥无几,尤其是去Python王国的吉森, 他怎么一点消息都没有呢? 是时候再派一个人去了......



推荐阅读
  • 使用Ubuntu中的Python获取浏览器历史记录原文: ... [详细]
  • 本文整理了Java面试中常见的问题及相关概念的解析,包括HashMap中为什么重写equals还要重写hashcode、map的分类和常见情况、final关键字的用法、Synchronized和lock的区别、volatile的介绍、Syncronized锁的作用、构造函数和构造函数重载的概念、方法覆盖和方法重载的区别、反射获取和设置对象私有字段的值的方法、通过反射创建对象的方式以及内部类的详解。 ... [详细]
  • 向QTextEdit拖放文件的方法及实现步骤
    本文介绍了在使用QTextEdit时如何实现拖放文件的功能,包括相关的方法和实现步骤。通过重写dragEnterEvent和dropEvent函数,并结合QMimeData和QUrl等类,可以轻松实现向QTextEdit拖放文件的功能。详细的代码实现和说明可以参考本文提供的示例代码。 ... [详细]
  • 开发笔记:加密&json&StringIO模块&BytesIO模块
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了加密&json&StringIO模块&BytesIO模块相关的知识,希望对你有一定的参考价值。一、加密加密 ... [详细]
  • 目录实现效果:实现环境实现方法一:基本思路主要代码JavaScript代码总结方法二主要代码总结方法三基本思路主要代码JavaScriptHTML总结实 ... [详细]
  • 本文介绍了Java工具类库Hutool,该工具包封装了对文件、流、加密解密、转码、正则、线程、XML等JDK方法的封装,并提供了各种Util工具类。同时,还介绍了Hutool的组件,包括动态代理、布隆过滤、缓存、定时任务等功能。该工具包可以简化Java代码,提高开发效率。 ... [详细]
  • Java容器中的compareto方法排序原理解析
    本文从源码解析Java容器中的compareto方法的排序原理,讲解了在使用数组存储数据时的限制以及存储效率的问题。同时提到了Redis的五大数据结构和list、set等知识点,回忆了作者大学时代的Java学习经历。文章以作者做的思维导图作为目录,展示了整个讲解过程。 ... [详细]
  • 本文介绍了OC学习笔记中的@property和@synthesize,包括属性的定义和合成的使用方法。通过示例代码详细讲解了@property和@synthesize的作用和用法。 ... [详细]
  • 本文讨论了一个关于cuowu类的问题,作者在使用cuowu类时遇到了错误提示和使用AdjustmentListener的问题。文章提供了16个解决方案,并给出了两个可能导致错误的原因。 ... [详细]
  • XML介绍与使用的概述及标签规则
    本文介绍了XML的基本概念和用途,包括XML的可扩展性和标签的自定义特性。同时还详细解释了XML标签的规则,包括标签的尖括号和合法标识符的组成,标签必须成对出现的原则以及特殊标签的使用方法。通过本文的阅读,读者可以对XML的基本知识有一个全面的了解。 ... [详细]
  • 闭包一直是Java社区中争论不断的话题,很多语言都支持闭包这个语言特性,闭包定义了一个依赖于外部环境的自由变量的函数,这个函数能够访问外部环境的变量。本文以JavaScript的一个闭包为例,介绍了闭包的定义和特性。 ... [详细]
  • Java在运行已编译完成的类时,是通过java虚拟机来装载和执行的,java虚拟机通过操作系统命令JAVA_HOMEbinjava–option来启 ... [详细]
  • 2021最新总结网易/腾讯/CVTE/字节面经分享(附答案解析)
    本文分享作者在2021年面试网易、腾讯、CVTE和字节等大型互联网企业的经历和问题,包括稳定性设计、数据库优化、分布式锁的设计等内容。同时提供了大厂最新面试真题笔记,并附带答案解析。 ... [详细]
  • 子类从父类继承所有的成员(字段,方法,嵌套类),构造方法不属于成员,所有子类不能继承,但是子类可以调用父类的构造方法对于private方法和属性,子类一定是继承了的,但是没有访问权 ... [详细]
  • Android系统启动过程分析一、Android平台架构首先贴一张Android系统架构图方便理解整个Android架构,这可以让我们从整体上对整个启动流程有个大概认知。可以看出整 ... [详细]
author-avatar
物业美女_959
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有