總的比較
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)的極好選擇。
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)建新的類,織入那些‘切面’代碼
python創(chuàng)建對象的過程

以這個為例
class Person:
def sayHello(self,name):
print("hello,"+name)
p = Person()
- 找到Person類的Metaclass
這里沒有, 到它父類里面找,一直找到, 還是沒有, 就用缺省的Metaclass,即type
- 找到Person類的Metaclass
- 用Metaclass 創(chuàng)建類對象
這里就用type創(chuàng)建 Person類對象
- 用Metaclass 創(chuàng)建類對象
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)
- 調(diào)用類對象的new方法 創(chuàng)建 實例
再調(diào)用init初始化
- 調(diào)用類對象的new方法 創(chuàng)建 實例
可以在運行時、動態(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語句了