`

用 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编程,它允许两个或多个用户通过网络进行通信。接下来,我们将深入研究...

    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)来建立连接,允许多个...

    即时通讯python仿QQ基本功能

    在Python中,我们可以通过PyQt5库来调用Qt5的功能,实现图形用户界面(GUI)的设计。PyQt5不仅封装了Qt5的所有组件,还支持Python的特性,使得编写GUI程序变得更为便捷。 本项目的核心技术包括以下几个方面: 1. *...

Global site tag (gtag.js) - Google Analytics