2016-02-26 163 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代码的方式。