python 和Java 對比

https://mp.weixin.qq.com/s/u3cSAOGQIe8DZGNr31qRZQ

總的比較

Python快速開發(fā),快速上線,快速迭代。等到發(fā)展到一定規(guī)模,動態(tài)語言的劣勢就會體現(xiàn)出來,維護/重構(gòu)難度高,
比如這個鴨子類型的應(yīng)用, 如果只看in_the_forest 定義不知道x是啥,不好讀, 如果要重構(gòu)改help方法名字, 也要一一人工去改

class Duck:  
    def help(self):  
        print( "Quaaaaaack! ")  
class Person:  
    def help(self):  
        print( "help me!" )  

def in_the_forest(x):  # 不知道 x 是什么
    x.help()  //如果想改help這個方法名, 不能批量ide自動改

in_the_forest(Duck())
in_the_forest(Person())

動態(tài)語言寫的代碼腐化速度要比靜態(tài)的Java要快一些。

Java呢,語法相對Python 啰嗦,表達力要弱一些,開發(fā)起來一板一眼,有很多規(guī)范,適合集團軍的大規(guī)模協(xié)同作戰(zhàn);有很多著名的框架和類庫,性能不錯,系統(tǒng)穩(wěn)定而成熟,是開發(fā)大型系統(tǒng)的極好選擇。

https://mp.weixin.qq.com/s/s9IykGHC-QY_smNprZgTmw

Python解釋器

說是解釋器,其實也是虛擬機, Python文件做了編譯,也形成了字節(jié)碼
基于棧的虛擬機 , 和jvm一樣

LOAD_FAST       0 (x)
LOAD_FAST       1 (y)
BINARY_ADD
LOAD_CONST      1 (10)
BINARY_MULTIPLY
RETURN_VALUE

垃圾回收: 主要是引用計數(shù),我還有標(biāo)記-清除,分代回收等算法作為輔助呢,從一個根集合開始,查找還被引用的,需要存活的對象, 不提供調(diào)優(yōu)選項,只要用就行了

單線程:只設(shè)置了一把鎖,Global Interpreter Lock ,簡稱GIL, 同一時刻,只有一個python線程能運行,
因為,程序的瓶頸啊,它不在CPU, 而在于IO,(用戶的輸入,數(shù)據(jù)庫的查許,網(wǎng)絡(luò)的訪問)
線程有超時,一個tick映射到一條或多條字節(jié)碼,執(zhí)行了100 ticks,解釋器就會發(fā)信號給 操作系統(tǒng),操作系統(tǒng)去調(diào)度那些因為沒有獲得GIL鎖而掛起的線程,去競爭這把鎖, 但是, 容易還是同一個線程搶到.

原因: 集成C
Python的設(shè)計目標(biāo)就是易于使用,易于擴展,很多用C語言寫的擴展庫被開發(fā)出來,有GIL, 這些擴展庫才能不必考慮線程安全問題,很容易被集成進來,
C的擴展庫極大地豐富了Python的功能,促進了Python的發(fā)展和使用

python 元編程

可以在運行時修改類
如下: Order類定義完以后, 給save方法加日志, 相當(dāng)于java的 aop

# 原來類的定義
class Order:
    def save(self):
        print ("save order")

# 動態(tài)改方法
old_save=Order.save
def save_with_logging(self):
    print ("logging start")
    old_save(self)
    print ("logging end")
Order.save=save_with_logging

調(diào)用的是新的save

t=Order()
t.save() 

aop: 對現(xiàn)有代碼做增強,動態(tài)地添加一些安全,日志,事務(wù)等
java的aop: Java 類一旦被裝載就無法修改,所以實現(xiàn)代碼的增強很麻煩
j在運行時生成新的類啊,讓新生成的類繼承老的類,或者和老的類實現(xiàn)同樣的接口,比如ASM這樣的工具,可以操作字節(jié)碼去創(chuàng)建新的類,織入那些‘切面’代碼

https://zhuanlan.zhihu.com/p/21379984

python創(chuàng)建對象的過程


以這個為例

class Person:
    def sayHello(self,name):
        print("hello,"+name)

p = Person()
    1. 找到Person類的Metaclass
      這里沒有, 到它父類里面找,一直找到, 還是沒有, 就用缺省的Metaclass,即type
    1. 用Metaclass 創(chuàng)建類對象
      這里就用type創(chuàng)建 Person類對象
def sayHello(self,name):
    print("hello,"+name)

#通過type來創(chuàng)建一個類對象,名稱為Person,這個類對象有一個方法sayHello
Person = type("Person",(),{"sayHello":sayHello})

↑和↓ 是一樣的

class Person:
    def sayHello(self,name):
        print("hello,"+name)
    1. 調(diào)用類對象的new方法 創(chuàng)建 實例
      再調(diào)用init初始化

可以在運行時、動態(tài)地創(chuàng)建一個全新的類!
自定義的Metaclass 可以: 攔截類的創(chuàng)建 讀取類的信息,做修改 ,返回新的類。
比如 用來ORM ,

from django.db import models

class Employee(models.Model):
    name = models.CharField(maxlength = 50)    
    age  = models.IntegerField()
    #其他代碼略#

這樣就2行就可以存入數(shù)據(jù)庫↓

employee = Employee(name="andy",age=20)  
employee.save()

原因就在Employee 的父類 Model, 有metaclass 是 Metaclass

class Model(metaclass=ModelBase):
    #其他代碼略

Metaclass里面實現(xiàn)了 ORM


ModelBase讀取列名、類型,在創(chuàng)建Employee類對象的時候,讀取了Employee類的定義信息 就可以形成insert, update,delete等SQL語句了

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容