2016-02-26 330 views
0

我有一個在Linux服務器上運行的python實例。我使用全局類創建了一個全局數組。我想把這個類的對象作爲一個命令行參數傳遞給我將在Windows VM上運行的python函數。如何在python中將對象作爲命令行參數傳遞? 或者有沒有更好的方法來做到這一點?如何在Python中傳遞對象作爲命令行參數?

+0

我們在這裏討論什麼對象?一個序列化的通用對象,或Python字符串/ int/dict/...文字作爲字符串? – timgeb

+0

@cdarke在技術上,你可以編碼的命令行參數,然後untickle,但是是... – timgeb

+1

*「或者有沒有更好的方式來做到這一點?」*任何更好的方式做什麼?你試圖解決什麼問題? – mzjn

回答

2

您可以使用json.dumps()json.loads()pickle.dumps()pickle.loads()爲了這個目的:

>>> import json 
>>> json.dumps(['Hi']) 
'["Hi"]' 
>>> json.loads(_) 
['Hi'] 

>>> import pickle 
>>> pickle.dumps(['Hi']) 
b'\x80\x03]q\x00X\x02\x00\x00\x00Hiq\x01a.' 
>>> pickle.loads(_) 
['Hi'] 

需要注意的是,如果你想在一個特殊的類來傳遞你將不得不做一些額外的工作;你需要有功能來轉換和從JSON格式,1,而醃菜會自動做事情,但仍然需要訪問該類。 2

但是,我認爲你最好在虛擬機上運行任務執行服務器。雖然這些服務器選項的主要重點是允許可伸縮性,但它們在遠程方面也相當出色。這將@JF的所有通信和序列化解決方案抽象出來。塞巴斯蒂安說,你真的不需要重塑。

芹菜可能是最常用的任務執行服務器庫。它需要一些工作來設置,但一旦配置就很容易使用:使用Celery裝飾器標記你的函數,使其成爲一個任務對象,在虛擬機上啓動worker,導入模塊,並調用具有相同參數的類方法你會傳遞給函數本身。 3一切正常後,芹菜工人可以設置爲Windows服務。 4

# app.py (adapted from examples in the Celery Getting Started tutorial 
from celery import Celery 

app = Celery('tasks', broker='amqp://[email protected]//') 

@app.task 
def my_function(a, b): 
    return a * b 


# main.py 
import app 

result = app.my_function.delay(4, 5) 
print result.get() 

雖然有時候,芹菜太麻煩了。如果您需要使用該函數中的第三方庫,那麼您必須將其導入到函數中,或者將它們安裝在Linux服務器上,這是由於Celery直觀的安排。我個人遇到了麻煩,讓芹菜首先成立。

更簡單的選擇是TaskIt。 5(完全披露:我是TaskIt的開發者)。它使用更傳統的服務器 - 客戶端連接風格,因此所有必須工作的都是標準的TCP套接字。默認情況下,它使用JSON序列化對象,但也支持pickle。

# server.py 
from taskit.backend import BackEnd 

def my_function(a, b): 
    return a * b 

backend = BackEnd(dict(my_function=my_function)) 
backend.main() 


# client.py 
from taskit.frontend import FrontEnd 

backend_addr = '127.0.0.1' 
frontend = FrontEnd([backend_addr]) 
print frontend.work('my_function', 4, 5) 
1

使用您將使用的任何方法在不同計算機上運行的進程之間進行通信。

multiprocessing module from stdlib支持這種用例。 Jupyter支持遠程內核。這是使用execnet的代碼示例。

如果首先將其序列化爲字符串,則可以將對象作爲命令行參數傳遞。但是沒有必要創建另一種遠程執行python代碼的方式。