2016-05-19 5 views
2

У меня есть программа GUI, которую я разработал в Python 3.2 для извлечения различных продуктов геопространственных данных. Мне нужно вызвать модуль, который я разработал в Python 2.7.Вызвать модуль Python 2.7 в Python 3.2

Я ищу способ вызова кода Python 2.7 с использованием интерпретатора Python 2.7 внутри программы Python 3.2. Я не могу перенести 2.7 на Python 3.2, поскольку он использует версию Python, установленную с ESRI ArcMap, и полагается на модуль дуги, который недоступен для Python 3. Моя единственная идея прямо сейчас заключается в использовании подпроцесса для вызова модуля в виде пакетного процесса однако это немного грязно, и я предпочел бы, чтобы у двух программ были некоторые отношения.

Заранее спасибо.

ответ

2

Попробуйте использовать subprocess.check_output(['C:\\python27\\python.exe', 'yourModule.py'])

Если вы хотите вызвать определенную функцию в пределах 27 файла, вы можете использовать несколько аргументов системы. Вызов будет выглядеть следующим образом:

subprocess.check_output(['C:\\python27\\python.exe', 'yourModule.py', 'funcName']) 

А в 27 файле вы можете добавить:

import sys 
if __name__=='__main__': 
    if 'funcName' in sys.argv: 
     funcName() 
    else: 
     #... execute normally 
+0

Знаете ли вы, что в любом случае я мог бы вызвать определенную функцию этого файла python с аргументами? – lamb

+0

Конечно! Я отредактировал мой ответ –

+0

Он работает на вас? –

2

Вы могли бы порождать процесс питон 2.7 в качестве сервера обработки запросов RPC от графического интерфейса пользователя, работающего на 3.2. Это будет работать либо по сети, либо по локальным каналам, либо по общей памяти, либо по шине сообщений вашей системы, либо по многим другим способам. Вам просто нужно перевести API вашей библиотеки в какие-то сериализованные сообщения.

Допустим, ваша библиотека имеет функцию: (супер упрощенный пример)

def add(a, b): 
    return a+b 

Вы бы обернуть это в каком-то сервере, скажем, flask app, который делает:

@app.route("/add", methods=["POST"]) 
def handle_add(): 
    data = request.get_json() 
    ret = your_lib.add(data['a'], data['b']) 
    return jsonify(ret) 

и на на стороне клиента, отправить и распаковать значения, используя что-то вроде requests

Вы даже можете сделать его достаточно прозрачным, реализовав перевод tor с методами, названными так же, как и сама библиотека, и делает import your_http_wrapper as your_library_name.

Трюк теперь заключается в том, чтобы убедиться, что все ваши параметры могут быть сериализованы и что вы можете реально отправить все аргументы/возвращаемые значения в разумные сроки для каждого вызова. Кроме того, вы теряете возможность изменять содержимое переменных, которые вы передаете оболочке, потому что сервер будет изменять только локальную копию (если вы не внесете в сериализацию все эти изменения)

1

Немного поздно, но если кто-то споткнется по этой теме:

Я написал module, который прозрачно запускает части программы в других интерпретаторах python. В основном он предоставляет декораторы и базовые классы, которые заменяют функции и объекты прокси-серверами, которые взаимодействуют с другими интерпретаторами.

Предназначен для обеспечения совместимости, например. работает python2 только код в python3 или доступ к модулям C от pypy.

В следующем примере цикл работает как 4x так быстро, используя pypy, как и в случае с python.

#!/usr/local/bin/python 
from cpy2py import TwinMaster, twinfunction 
import sys 
import time 
import math 


# loops in PyPy 
@twinfunction('pypy') 
def prime_sieve(max_val): 
    start_time = time.time() 
    primes = [1] * 2 + [0] * (max_val - 1) 
    for value, factors in enumerate(primes): 
     if factors == 0: 
      for multiple in xrange(value*value, max_val + 1, value): 
       primes[multiple] += 1 
    return {'xy': [ 
     [primes[idx] == 0 for idx in range(minidx, minidx + int(math.sqrt(max_val)))] 
     for minidx in range(0, max_val, int(math.sqrt(max_val))) 
     ], 'info': '%s in %.1fs' % (sys.executable, time.time() - start_time)} 


# matplotlib in CPython 
@twinfunction('python') 
def draw(xy, info='<None>'): 
    from matplotlib import pyplot 
    pyplot.copper() 
    pyplot.matshow(xy) 
    pyplot.xlabel(info, color="red") 
    pyplot.show() 

if __name__ == '__main__': 
    twins = [TwinMaster('python'), TwinMaster('pypy')] 
    for twin in twins: 
     twin.start() 
    data = prime_sieve(int(1E6)) 
    draw(**data) 
+0

еще использовать это, однако это выглядит очень полезно, спасибо! – lamb

Смежные вопросы