`

用 pickle 实现简易“跨”Python实现平台的调用

阅读更多

有一次在用 Python 开发的时候遇到个问题:既需要调用 .Net Assembly,又需要调用只支持 CPythonmodule.


对于前一种场景,我们只能用 IronPython 作为引擎。

对于后一种场景,我们只能用 CPython。

 

当时找到一种简易的方法:遇到需要调用的模块不支持当前 Python 引擎时,让另一个 Python 引擎在独立的进程中执行目标方法,通过进程通信的方式传递参数及执行结果

 

为了降低进程通信时的复杂度,参数和执行结果在传递前都会先被序列化,另一进程收到信息后再反序列化。这就用到了 pickle。

 

上示例代码:

python_proxy.py:

 

import pickle

# Python 引擎
PYTHON = 'python'
IPY = 'ipy'

def invoke(driver, cmd_format, *args, **kwargs):
    # 将参数序列化后保存到文件中
    argFile = _dump((args, kwargs))

    # 将存储参数的文件地址作为参数传给另一个 Python 引擎
    from subprocess import Popen, PIPE
    p = Popen([driver, '-c', cmd_format % argFile],
              stdout = PIPE,
              stderr = PIPE)
    out, err = p.communicate()
    if err:
        raise AssertionError(err)

    # 获取存有返回值的文件地址,读取内容,并反序列化得到最终结果
    resultFile = out.strip()
    result = _load(resultFile)

    # 删除存储参数和反回值的临时文件
    import os
    os.remove(argFile)
    os.remove(resultFile)

    return result

def execute_with_file_arg(func, file):
    # 读取文件内容,将其反序列化得到参数
    args, kwargs = _load(file)

    # 执行目标方法,并将序列化后的返回值存储到文件中,输出该文件地址
    print _dump(func(*args, **kwargs))

def _load(file):
    with open(file, 'rb') as f:
        return pickle.load(f)

def _dump(o):
    import tempfile
    with tempfile.NamedTemporaryFile(delete = False) as f:
        pickle.dump(o, f)
    return f.name

 

test_module.py:

import python_proxy
import platform

current_driver = platform.python_implementation()

def func_common(num1, num2):
    # 假设该方法核心代码必须在 IronPython 环境下执行

    # 当前环境不是 IronPython:需要交给 IronPython 执行
    if current_driver != 'IronPython':
        return _func_for_non_ipy(num1, num2)

    # 当前环境是 IronPython:直接运行核心代码并返回结果
    return num1 + num2

def _func_for_non_ipy(num1, num2):
    # 交给 IronPython 运行时所提供的命令格式
    # 用参数文件地址格式化后可得到最终命令
    cmd_format = 'import test_module; test_module.func_with_file_arg(r"%s")'
    return python_proxy.invoke(python_proxy.IPY, cmd_format, num1, num2)

def func_with_file_arg(file):
    python_proxy.execute_with_file_arg(func_common, file)

 

调用(是不是 IronPython 环境都可以):

 

import test_module
print test_module.func_common(1, 2)

 

该方法只是一个简易的取巧方法。

 

上述示例代码有一个很明显的弱点:如果在目标方法的核心代码中输出其它内容(如:在 'return num1 + num2' 前添加 'print "dummy message"'),将导致进程通信时拿到的输出信息包含这些内容,而不仅仅是我们想要的结果文件路径。

 

另外,该方法并不是真正的跨 Python 实现平台,只是在运行时调用其它 Python 平台来暂时替代。所以 IronPython 和 CPython 都得安装。而且如果有更多各种复杂的信息需要在两个 Python 平台之间共享(如:权限认证信息等),将会非常复杂。

Keep it simple, stupid!

 

0
0
分享到:
评论

相关推荐

    Python使用pickle模块存储数据报错解决示例代码

    pickle模块只能在python中使用,python中几乎所有的数据类型(列表,字典,集合,类等)都可以用pickle来序列化, pickle序列化后的数据,可读性差,人一般无法识别。 接下来我们看下Python使用pickle模块存储数据...

    python tkinter pickle 实现注册登陆页面

    而pickle模块则是Python中用于序列化和反序列化的工具,它能将Python对象转化为字节流,便于存储和传输。在这个"python tkinter pickle 实现注册登陆页面"项目中,我们将探讨如何使用这两者来构建一个简单的用户注册...

    Python基础——pickle(保存与提取数据)

    pickle 是一个 python 中, 压缩/保存/提取 文件的模块. 最一般的使用方式非常简单. 比如下面就是压缩并保存一个字典的方式. 字典和列表都是能被保存的. import pickle dict_ = {'red':1,'green':2,'blue':3} file = ...

    Qt5调用python,并且后去python的结构数据

    同时,为了实现更深入的交互,例如传递复杂的数据结构,可以使用Python的`pickle`模块将Python对象序列化为字符串,然后在Qt中反序列化。 下面是一个简单的步骤来实现这个过程: 1. **设置环境**:确保你的系统...

    Python 文件处理 09_使用pickle实现序列化和反序列化_神经元记忆移植.mp4

    Python 文件处理 09_使用pickle实现序列化和反序列化_神经元记忆移植.mp4

    Python 中Pickle库的使用详解

    Pickle模块与Python其他序列化标准模块json相比,json模块能够生成人类可读的文本数据,可以直接打开查看,适合简单的数据交换,但对于复杂的数据结构或者自定义对象的保存,json可能就不够用了,这时候就需要pickle...

    Python库 | pickle-mixin-1.0.2.tar.gz

    Python库pickle-mixin-1.0.2是一个用于序列化和反序列化的工具,它扩展了Python内置的pickle模块。pickle模块是Python中用于将对象的状态转化为可存储或可传输格式,以及从这种格式恢复对象的原状的工具。这个库的...

    gopickle:Go库,用于加载用pickle和PyTorch模块文件序列化的Python数据

    pickle子包提供了核心功能,用于从文件,字符串或字节序列中加载使用Python pickle模块序列化的数据。 支持从0到5的所有pickle协议。 pytorch子软件包实现了用于加载PyTorch模块文件的类型和功能。 支持现代zip压缩...

    用python3读取python2的pickle数据方式

    然而,由于Python 2和Python 3在字符串处理上的差异,当尝试用Python 3读取在Python 2环境下序列化的pickle数据时,可能会遇到一些兼容性问题。本文将详细介绍如何解决这些问题,以便在Python 3环境中顺利读取Python...

    python用pickle模块实现“增删改查”的简易功能

    ### Python使用Pickle模块实现“增删改查”简易功能详解 #### 概述 在Python编程语言中,`pickle`模块提供了序列化与反序列化的功能,这使得我们可以将几乎任何类型的Python对象(例如列表、字典等)转换成一个...

    Python使用pickle模块实现序列化功能示例

    pickle模块是Python中一个内建的标准库,它提供了对Python对象进行序列化和反序列化的功能。 pickle模块支持多种Python数据类型和一些自定义对象的序列化。通过pickle模块,可以将Python对象转换成字节流(一个字节...

    jsonpickle:Python库,用于将任意对象图序列化为JSON。 它几乎可以使用任何Python对象并将该对象转换为JSON。 此外,它可以将对象重新构造回Python

    jsonpickle ... 使用json格式,jsonpickle允许将简单的数据类型以人类可读的格式存储,并且将更复杂的数据类型(例如numpy数组和pandas数据帧)在支持json的任何平台上以机器可读的方式存储。 例如,与

    python3内置持久化模块pickle心得

    `pickle`是Python的一个内置模块,用于实现Python对象的序列化和反序列化。通过`pickle`,我们可以将Python中的各种数据结构(如列表、字典、元组等)转换成一个字节流(bytes),这样就可以方便地在网络上传输或者...

    python中的Pickle文件和npy文件(csdn)————程序.pdf

    Pickle和Numpy模块提供了两种不同的方式来实现这一目标。 1. **Pickle文件**: - **介绍**:Pickle模块是Python内置的一种序列化和反序列化的库,它可以将Python对象转化为字节流(序列化),然后将这个字节流还原...

    Python pickle模块实现对象序列化

    这篇文章主要介绍了Python pickle模块实现对象序列化,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 作用 对Python对象进行序列化,便于存储和传输 Python...

    python实现QQ基本功能(python实现聊天工具)

    在本项目中,我们主要探讨如何使用Python编程语言来实现一个基本的QQ功能,即创建一个无图形用户界面(GUI)的聊天工具。这个工具基于socket编程,它允许两个或多个用户通过网络进行通信。接下来,我们将深入研究...

    python实现车辆路径轨迹移动的上位机程序

    在这个特定的案例中,"python实现车辆路径轨迹移动的上位机程序"指的是利用Python来创建一个能够模拟和显示车辆移动轨迹的控制台或者图形用户界面(GUI)应用程序。这种类型的程序在交通监控、物流调度或者游戏开发...

    The-windows-pickle-login-tkinter-python-project

    The-windows-pickle-login-tkinter-python-project Python的标准TK GUI工具包的接口Tkinter模块(“TK界面”)是Python的标准TK GUI工具包的接口。 TK和Tkinter可以用于大多数UNIX平台,也可以应用于windows和麦金塔...

    多人聊天室python实现

    【标题】"多人聊天室python实现"涉及到的核心技术是使用Python编程语言构建一个支持多用户交互的聊天系统。在Python中,这样的应用通常基于网络通信协议TCP(Transmission Control Protocol)来建立连接,允许多个...

Global site tag (gtag.js) - Google Analytics