当前位置: 首页 > 编程日记 > 正文

Java帝国对Python的渗透能成功吗?

640?wx_fmt=jpeg


作者 | 刘欣

转载自码农翻身(公众号 ID:coderising)


引子


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大臣全权负责,一年后看效果。”


泛型


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


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


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


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


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


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


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


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


List<String> files = new ArrayList<String>(); 

String file = files.get(0);  //不必做强制类型转换 

files.add(new File(.....)) ;  // 编译错误  


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


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


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


反射


吉森觉得有点被 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真是不错,他都有点羡慕了。


动态代理


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


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


640?wx_fmt=png


吉森说道:“老先生,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居然在源码级别就把功能给增强了!


锦囊妙计


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


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


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


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


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


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


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


真相大白


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


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


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


(本文为 AI科技大本营转载文章,转载请联系原作者)


征稿


640?wx_fmt=png

推荐阅读:

  • 300道Python面试题,备战春招!

  • 2018中国开发者真实现状:40岁不做开发,算法工程师最稀缺!

  • Python之父龟叔推荐的学习视频,有趣、好玩,全是好评!

  • 数据分析奥斯卡女神们,谁是你心中的No.1?

  • 5年Go语言经验薪资翻倍! 这份全球职业报告中, 区块链开发者薪资排第三, 前两名你绝对想不到!(含完整版下载资源)

  • 女神节 | 那些奋斗在IT领域的“女神”们

  • 聊天宝解散,多闪、马桶MT还会远吗?| 畅言

  • 程序员撒狗粮!3 天开发自己的婚礼小程序!

  • 为啥程序员下班后只关显示器从不关电脑?

640?wx_fmt=png

❤点击“阅读原文”,查看历史精彩文章。

相关文章:

【杂】突然有个想法,为了防止公司或其他,监视你的qq或微信,可以做个程序,将信息打乱,分别用qq和微信传输,然后,再还原

突然有个想法&#xff0c;为了防止公司或其他&#xff0c;监视你的qq或微信&#xff0c;可以做个程序&#xff0c;将信息打乱&#xff0c;分别用qq和微信传输&#xff0c;然后&#xff0c;再还原。

CTO 基本功大盘点 —— 没有这些技能,谈何远大前程?

本文由 「TGO鲲鹏会」原创&#xff0c;原文链接&#xff1a;CTO 基本功大盘点 —— 没有这些技能&#xff0c;谈何远大前程&#xff1f; 作者&#xff5c;刘海星 2018 年马上就要过去六分之一了&#xff0c;你的 KPI 完成多少了&#xff1f; 别沮丧&#xff0c;其实我想说的是&…

Windows Phone 7 不温不火学习之《创建用户控件》

同样出自微软的产品&#xff0c;像ASP.NET 一样&#xff0c;Windows Phone 7 也有一个叫UserControl 的东西。这个相当于一个组件&#xff0c;类似于Android 继承View 。 本篇将实现一个用户控件&#xff0c;默认为它添加高宽&#xff0c;并为它添加一个自己的事件&#xff0c;…

从起源、变体到评价指标,一文解读NLP的注意力机制

作者 | yuquanle转载自AI小白入门&#xff08;ID:StudyForAI&#xff09;目录1.写在前面2.Seq2Seq 模型3.NLP中注意力机制起源4.NLP中的注意力机制 5.Hierarchical Attention6.Self-Attention7.Memory-based Attention 8.Soft/Hard Attention9.Global/Local Attention10.评价指…

【Git】ubuntu上git commit提交后如何保存和退出类似vim的界面,回到命令行

问题 使用 git commit 命令后&#xff0c;进入类似vim的界面&#xff0c;开始时&#xff0c;不知道如何保存&#xff0c;甚至不知道怎么退出该界面。 解决方法 1、使用 git commit 命令后&#xff0c;进入的是nano文本编辑器&#xff08;类似vim&#xff09;&#xff1b; 2…

linux硬盘满了问题排查

关键指令&#xff1a; df du find step1&#xff1a; 如果发现硬盘满了&#xff0c;首先要确定一下&#xff0c;使用df查看硬盘使用情况 df -h step2&#xff1a; 从第一步结果判定满了&#xff0c;确定哪些文件或哪个文件占了大头&#xff0c;使用du指令做逐步排查&#xff0c…

win2003登陸及關機設定

開啟未登陸可以關機鍵關機﹕ 到控制面板&#xff0c;本地安全策略&#xff0c;安全性選項﹐启用允许在未登录前关机 關關機事件跟踪﹕ 运行“gpedit.msc”命令打开组策略编辑器&#xff0c;依次展开“计算机配置”→“管理模板”→“系统”&#xff0c;将“顯示关闭事件跟踪程序…

【Qt】信号和槽对值传递参数和引用传递参数的总结

在同一个线程中 当信号和槽都在同一个线程中时&#xff0c;值传递参数和引用传递参数有区别&#xff1a; 值传递会复制对象&#xff1b;&#xff08;测试时&#xff0c;打印传递前后的地址不同&#xff09; 引用传递不会复制对象&#xff1b;&#xff08;测试时&#xff0c;…

Node.js入门(含NVM、NPM、NVM的安装)

本文最初发表于博客园&#xff0c;并在GitHub上持续更新前端的系列文章。欢迎在GitHub上关注我&#xff0c;一起入门和进阶前端。 以下是正文。 Node.js的介绍 引擎 引擎的特性&#xff1a; JS的内核即引擎。因为引擎有以下特性&#xff1a; &#xff08;1&#xff09;转化的作…

GitHub日收7000星,Windows计算器项目开源即爆红!

说起此番微软开源 Windows 计算器&#xff0c;有道是“春风得意马蹄疾&#xff0c;一日‘摘星’ 7000”……整理 | 仲培艺来源 | CSDN&#xff08;ID&#xff1a;CSDNnews&#xff09;微软又来给自己拥抱开源的决心送”证明素材“了&#xff01;昨日&#xff0c;微软官宣在 MIT…

域环境下的***

首先还是先简要看一下域的概念吧&#xff1a; 域 (Domain) 是Windows网络中独立运行的单位&#xff0c;域之间相互访问则需要建立信任关系(即Trust Relation)。信任关系是连接在域与域之间的桥梁。当一个域与其他域建立了信任关系后&#xff0c;2个域之间不但可以按需要相互进行…

如何重构“箭头型”代码

本文主要起因是&#xff0c;一次在微博上和朋友关于嵌套好几层的if-else语句的代码重构的讨论&#xff08;微博原文&#xff09;&#xff0c;在微博上大家有各式各样的问题和想法。按道理来说这些都是编程的基本功&#xff0c;似乎不太值得写一篇文章&#xff0c;不过我觉得很多…

让数百万台手机训练同一个模型?Google把这套框架开源了

作者 | 琥珀出品 | AI科技大本营&#xff08;公众号id&#xff1a;rgznai100&#xff09;【导语】据了解&#xff0c;全球有 30 亿台智能手机和 70 亿台边缘设备。每天&#xff0c;这些电话与设备之间的交互不断产生新的数据。传统的数据分析和机器学习模式&#xff0c;都需要在…

【OpenCV】cv::VideoCapture 多线程测试

cv::VideoCapture多线程测试结果&#xff1a; 在多线程中使用抓取摄像头视频帧时线程安全的&#xff0c;但是&#xff0c;多个线程会共用摄像头的总帧率。 比如&#xff0c;我用两个线程测试30帧的摄像头&#xff0c;每个线程差多都是15帧。

都有Python了,还要什么编译器!

编译的目的是将源码转化为机器可识别的可执行程序&#xff0c;在早期&#xff0c;每次编译都需要重新构建所有东西&#xff0c;后来人们意识到可以让编译器自动完成一些工作&#xff0c;从而提升编译效率。但“编译器不过是用于代码生成的软机器&#xff0c;你可以使用你想要的…

【Qt】Qt发布程序时,报错: could not find or load the Qt platform plugin xcb

问题描述 Qt程序在发布时&#xff0c;报错&#xff1a; This application failed to start because it could not find or load the Qt platform plugin “xcb” in “”. Reinstalling the application may fix this problem Aborted (core dumped) 原因 没有将libqxcb…

jsky使用小记

jsky是一款深度WEB应用安全评估工具&#xff0c;能轻松应对各种复杂的WEB应用&#xff0c;全面深入发现里面存在的安全弱点。 jsky可以检测出包括SQL注入、跨站脚本、目录泄露、网页木马等在内的所有的WEB应用层漏洞&#xff0c;渗透测试功能让您熟知漏洞危害。 打开——新建扫…

BSP场景管理方法简介

BSP&#xff08;Binary Space Partition,二叉空间分割&#xff09;方法&#xff0c;在大型3d游戏场景管理方面&#xff0c;可以认为是已经证明了的&#xff0c;最成熟的&#xff0c;最经得起考验的场景管理方法。诸如虚幻系列引擎&#xff08;Unreal 1,2,3&#xff09;&#xf…

【Qt】Qt样式表总结(一):选择器

官方资料 https://blog.csdn.net/u010168781/article/details/81868523 注释 qss文件中使用:/**/ 来注释 样式规则 样式表由样式规则序列组成。样式规则由选择器和声明组成。选择器指定受规则影响的部件;声明指定应在小部件上设置哪些属性。 如: QLabel { color: white;…

JVM-01:类的加载机制

本文从  纯洁的微笑的博客  转载 原地址&#xff1a;http://www.ityouknow.com/jvm.html 类的加载机制 1、什么是类的加载 类的加载指的是将类的.class文件中的二进制数据读入到内存中&#xff0c;将其放在运行时数据区的方法区内&#xff0c;然后在堆区创建一个java.lang.…

CVPR 2019 | 惊艳的SiamMask:开源快速同时进行目标跟踪与分割算法

作者 | 周强&#xff08;CV君&#xff09;来源 | 我爱计算机视觉&#xff08;公众号id&#xff1a;aicvml&#xff09;责编 | Jane上面这张Gif图演示了 SiamMask 的效果&#xff0c;只需要鼠标滑动选择目标的包围框&#xff0c;即可同时实现目标跟踪与分割。这种视频里目标的像…

看看Entity Framework 4生成的复杂的分页SQL语句

之前发现Entity Framework 4生成的COUNT查询语句问题&#xff0c;今天又发现它生成的分页SQL语句问题&#xff0c;而LINQ to SQL却不存在这个问题。 >>> 来看一看&#xff0c;瞧一瞧&#xff01; 上代码&#xff1a; 看生成的SQL语句&#xff1a; 1. Entity Framework…

这份“插件英雄榜Top20”才是Chrome的正确打开方式!

作者 | zhaoolee整理 | Jane出品 | AI科技大本营&#xff08;公众号id&#xff1a;rgznai100&#xff09;前言”一入开源深似海”&#xff01;给大家推荐优秀的开源项目、实用工具已经成为 AI科技大本营的固定节目。“我待开源如初恋”&#xff0c;逛淘宝&#xff0c;点收藏&am…

【Qt】Qt样式表总结(二):冲突和命名空间

Qt样式表总结&#xff08;一&#xff09;&#xff1a;选择器 解决冲突 针对同一个控件的相同属性&#xff0c;使用多种选择器时&#xff0c;会出现冲突。如&#xff1a; QPushButton#okButton { color: gray } QPushButton { color: red } 解决冲突的规则是&#xff1a;更…

编程自动化,未来机器人将超越人类?

近年&#xff0c;创业者陈曦正专注于一个项目——编程自动化。即机器人可以自己编程&#xff0c;这到底意味着什么呢&#xff1f; 在美国科幻大片《终结者2》中&#xff0c;20世纪末的1997年7月3日&#xff0c;人类研制的全球高级计算机控制系统“天网”全面失控&#xff0c;机…

Repeater 嵌套 Repeater

作为一个刚入行的IT小鸟&#xff0c;每天学习&#xff0c;是必须的&#xff01; 光自学肯定是不够的&#xff01;由于本人IQ比较低&#xff0c;经常一个小问题都会想不明白。 还好有媳妇儿的帮助&#xff0c;才把这个功能给实现了。 现在就在这里总结下&#xff0c;以示敬意。o…

【Qt】Qt样式表总结(三):QObject 属性

【Qt】Qt样式表总结(一):选择器 【Qt】Qt样式表总结(二):冲突和命名空间 QObject 属性 可以使用 qproperty < 属性名称 > 语法,设置任何可以Q_PROPERTY的控件 MyLabel { qproperty-pixmap: url(pixmap.png); } MyGroupBox { qproperty-titleColor: rgb(100, 2…

CVPR2019 | 斯坦福学者提出GIoU,目标检测任务的新Loss

作者 | Slumbers&#xff0c;毕业于中山大学&#xff0c;深度学习工程师&#xff0c;主要方向是目标检测&#xff0c;语义分割&#xff0c;GAN责编 | Jane本文是对 CVPR2019 论文《Generalized Intersection over Union: A Metric and A Loss for Bounding Box Regression》的解…

ASP.NET页面之间传递值的几种方式

页面传值是学习asp.net初期都会面临的一个问题&#xff0c;总的来说有页面传值、存储对象传值、ajax、类、model、表单等。但是一般来说&#xff0c;常用的较简单有QueryString&#xff0c;Session&#xff0c;Cookies&#xff0c;Application&#xff0c;Server.Transfer。 一…

下一代安全威胁的内幕故事

当伊朗总统马哈茂德艾哈迈迪&#xff0d;内贾德在去年11月份宣布该国的核计划遭到软件***后&#xff0c;他证实了许多安全研究人员的猜测&#xff1a;原因是Stuxnet大爆发&#xff0c;篡改了控制处理铀所用的离心机电机的关键系统。 内贾德对这起***造成的影响轻描淡写&#xf…