歡迎光臨
每天分享高質量文章

Python和Java的硬碟夜話

來自:碼農翻身(微信號:coderising)

這是一個程式員的電腦硬碟,在一個叫做“學習”的目錄下曾經生活著兩個小程式,一個叫做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:	mpHello.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和指標》的電子書上坐著,目光獃滯地對他倆說:“你們好,歡迎來到回收站。看來主人又有了新歡,把你們倆也拋棄了。


●編號416,輸入編號直達本文

●輸入m獲取文章目錄

推薦↓↓↓

 

Java編程

更多推薦:18個技術類微信公眾號

涵蓋:程式人生、演算法與資料結構、黑客技術與網絡安全、大資料技術、前端開發、Java、Python、Web開發、安卓開發、iOS開發、C/C++、.NET、Linux、資料庫、運維等。

赞(0)

分享創造快樂