讓Python程序在線執行

引言

用python編程是我最幸福的時刻,相信有過python編程經驗的童鞋都有體會。沒有過多的束縛,沒有過多的技巧,即使只用最平實的代碼也依然能完成想要的功能。如果可以,我真希望這輩子只用python和c編程。

長久以來native應用爲了能將新版本推送給用戶,都是採用自動更新的方案。後來出現了hybrid應用,用native做個容器承載web內容,這樣新的內容可以直接在線載入給用戶。但hybrid應用有一些明顯的弊端:

  1. 帶有沉重的運行時,爲了能渲染web頁面,一個渲染引擎運行時就有好幾十M。
  2. 接口功能有限,因爲js天生被設計爲運行在沙箱裏,所以較爲敏感的底層接口都需要渲染引擎或者native容器提供接口進行擴展,功能性更新時web頁面更新還不夠,還得讓底層的native容器也更新。

hybrid的這些弊端native代碼都沒有,但native同樣沒有web頁面的即時推送最新內容的能力,都說python是一個膠水語言,這個時候如果能讓python介入調和這些問題實在是再好不過了。python代碼可以即時解釋執行,它的標準運行時只有4M,而且藉助cffi使用ctypes調用底層接口實在是跟玩一樣。那擺在面前的問題顯而易見,如果能讓python腳本像web頁面一樣被即時加載解釋執行就好了。

pygain

讓python腳本獲得web頁面的即時加載解釋執行功能我們可以藉助一個叫pygain的庫,pypi上的地址是: pygain。可以直接使用pip install pygain安裝,使用pygain只需要import pygain加載即可,現在假設我們要加載一個存放在遠程服務器上叫hello.py的腳本在http://oeb1qxnpc.bkt.clouddn.com/hello.py,它看起來像是這樣:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @author: zig([email protected])

print("hello, pygain")

就是說加載這個腳本(import hello)我們將在標準輸出得到”hello, pygain”。我們在本地編寫一個測試腳本test.py:

import pygain

pygain.gain("hello", "http://oeb1qxnpc.bkt.clouddn.com", ["py"])

import hello

運行這個腳本,不出意外我們將得到”hello, pygain”的輸出。

上例中import pygain之後使用pygain.gain接口會註冊一個叫hello的頂層模塊,http://oeb1qxnpc.bkt.clouddn.com是這個頂層模塊的根地址,此後import hello或者import hello.submodule(導入hello的子模塊)都將以這個根地址進行遍歷尋找,這個流程與導入文件系統上的模塊沒有什麼區別。["py"]說明了這次註冊後,import hello或者import hello.submodule之類的導入指令將會尋找的文件後綴,接下來我們會看到導入在線的zip包會是更普遍的場景。

一次性加載一堆python腳本

儘管我們可以把一堆python腳本扔在遠程服務器上,然後使用import指令時觸發pygain類似文件系統的尋找規則去一一尋找需要的腳本文件,但這種方式是極其低效的:一個python腳本通常不會有多大,這樣尋找它的耗時比加載它耗時還要長。所以pygain提供了可以導入zip包的功能。現在假設我們要加載一個存放在遠程服務器上叫demo.zip的包在http://oeb1qxnpc.bkt.clouddn.com/demo.zip,這個zip包的內容是這樣:

>

demo.zip

/- init.py

/- hello.py

/- hello2.py

我們在本地編寫一個測試腳本test.py:

import pygain

pygain.gain("demo", "http://oeb1qxnpc.bkt.clouddn.com", ["zip", "py"])

import demo.hello2

運行這個腳本,不出意外我們將得到”hello, pygain”的輸出。

關鍵字參數

pygain還提供了一些keyword arguments(關鍵字參數):
1. httpheaders: 用於在發送http請求時附加的http頭
2. zippw: 用於在加載加密zip包時進行解密

pygain.gain("demo", "http://zagzig.me/pygain/demo/v1", ["zip", "py"],
  httpheaders={"Referer": "xxx"}, zippw="guesswhat")

一些場景

結合PyQt5

從我們團隊的本身實踐來講,結合PyQt使用pygain是一個有趣且高效的套路:
1. 產品的安裝包總是使用pygain導入一個遠程服務器的”引導腳本”,之所以被稱爲”引導腳本”,是因爲它本身不幹啥,只是用來導入特定版本的zip包。
2. 每次產品更新將代碼打個zip包放到一個以版本命名的文件夾,然後把”引導腳本”指向這個版本的zip包。
3. 必要時還可以通過”引導腳本”進行版本回溯。
PyQt提供了一整套的工具鏈以至於將資源文件都可以轉化爲python文件,這樣不管是更新GUI,還是更新功能,都可以通過pygain導入整個zip包完成。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章