Uso simples de arquivos python3 chamando python2

Principais diferenças entre Python 3 e Python 2

O Python 3 quebra a compatibilidade com versões anteriores do Python 2. Mas não é um redesenho completo. Além disso, não quer dizer que a versão 2.x do módulo Python não possa ser executada no Python 3. O código pode ser totalmente compatível com versões cruzadas e executado em ambas as versões sem ferramentas ou técnicas adicionais, mas isso geralmente só é possível com aplicativos simples.
As diferenças importantes introduzidas pelo Python 3 geralmente podem ser divididas nos seguintes aspectos:
• Mudanças de sintaxe, alguns elementos de sintaxe foram excluídos/modificados e alguns novos elementos de sintaxe foram adicionados.
• Alterações na biblioteca padrão.
• Mudanças nos tipos de dados e coleções.

Portanto, às vezes, devido a algumas razões objetivas, os arquivos Python 2 precisam ser introduzidos no ambiente python3 e os dois não são totalmente compatíveis, portanto, alguns outros designs são necessários. O seguinte é um método simples para implementação específica.

determinar necessidades

No meu projeto, um arquivo de verificação de atributo é projetado por meio do ambiente pyhton3; mas minha verificação de gráfico (topologia) é projetada com base no pacote de site ArcGIS ArcPy, ambos os quais obviamente não podem ser executados no ambiente pyhton3. (ArcPy suporta apenas python2.7)

Eu preciso chamar meu arquivo de inspeção projetado python2.7 no ambiente python3.

Implementação

Use o módulo de subprocesso (gerenciamento de subprocessos) da biblioteca padrão do python; o módulo de subprocesso permite gerar novos processos, conectar suas entradas, saídas e canais de erro e obter seus códigos de retorno. Este é um link para a documentação oficial do python

ps: Claro, você também pode usar o módulo de multiprocessamento (paralelo baseado em processo) para obter a mesma função.

script = [self.obj.exename, ".\\recourse\\CheckTopology.py", self.obj.filename]
proc = subprocess.Popen(script, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
proc.communicate()

Acima, use o construtor Popen para abrir um processo filho chamado proc, e a instância da classe Popen possui os seguintes métodos:
Popen.poll()
verifica se o processo filho foi encerrado. Define e retorna a propriedade returncode. Caso contrário, retorna Nenhum.
Popen.wait(timeout=None)
espera que o processo filho seja encerrado. Define e retorna a propriedade returncode. Se o processo não for interrompido após segundos de tempo limite, uma exceção TimeoutExpired é lançada, que pode ser capturada com segurança e aguardada novamente.
NOTA: Ocorrerá um impasse quando stdout=PIPE ou stderr=PIPE e o processo filho produzir saída suficiente para o pipe para impedir que o buffer do pipe do sistema operacional receba mais dados. Use Popen.communicate() para contorná-lo ao usar pipes.
Popen.communicate(input=None, timeout=None)
Interagir com o processo: enviar dados para stdin. Lê os dados de stdout e stderr até que o fim do arquivo seja atingido. Aguarda o término do processo e define a propriedade returncode.
Popen.terminate()
interrompe o processo filho.
Popen.kill ()
mata o processo filho.

Aqui, escolha Popen.communicate, o motivo é obter as informações de saída do processo filho para monitorar a operação do processo filho; o script acima é a lista de informações de abertura do processo filho, uso como [python2.exe, my. py, argv] da esquerda para a direita, o programa de execução, o arquivo py e os parâmetros do arquivo py são usados ​​para abrir o subprocesso; stdout=subprocess.PIPE é abrir o pipeline para obter a saída padrão e stderr=subprocess. STDOUT é abrir o pipeline para obter a saída de erro.

comunica() retorna uma tupla (stdout_data, stderr_data). Uma string se o arquivo foi aberto no modo de texto; caso contrário, bytes.

outs, errs = proc.communicate()
outs, errs é a informação de saída do processo filho.

Exemplo de projeto

O conteúdo a seguir faz parte do arquivo final do meu projeto: Como as informações de saída do subprocesso precisam ser exibidas na interface GUI, outro loop de thread é aberto para enviar as informações de saída do processo na forma de um sinal.

 def Threading_topo(self):  # CheckTopology子进程输出读取方法
        script = [self.obj.exename, ".\\recourse\\CheckTopology.py", self.obj.filename]

        def output_reader(proc, outq):
            for line in iter(proc.stdout.readline, b''):
                outq.put(line.decode('gbk'))

        def main(script1):
            # Note the -u here: essential for not buffering the stdout of the subprocess
            proc = subprocess.Popen(script1, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
            outq = queue.Queue()
            t = threading.Thread(target=output_reader, args=(proc, outq))
            t.start()

            try:
                for i in range(500):
                    if proc.poll() == 0:
                        self.sinOut.emit('......拓扑检查完成。\n')
                        proc.terminate()
                        break
                    print(i)
                    try:
                        line = outq.get(block=False)
                        # 这里是我最终的输出信息
                        self.sinOut.emit(line)
                    except queue.Empty:
                        pass

                    time.sleep(1)
            finally:
                proc.terminate()
                try:
                    proc.wait(timeout=1)
                    print('== subprocess exited with rc =', proc.returncode)
                except subprocess.TimeoutExpired:
                    print('subprocess did not terminate in time')
            t.join()

        main(script)

Resumo e Reflexão

if __name__ == "__main__":
    in_path = sys.argv[1]
    my_Topology = CheckTopology(in_path)
    my_Topology.CreateNewGdb()
    my_Topology.CreateFeatureDataset()
    my_Topology.CreateTopology()
    my_Topology.AddRules_ValidateTopology()

Este é o fim do meu arquivo python2. Para garantir que o arquivo python2 seja executado normalmente de forma independente, passe os parâmetros necessários para o arquivo no formulário acima; aqui meu parâmetro é in_path, que está listado na lista de scripts do subprocesso aberto de acordo com Os parâmetros externos adquiridos pelo contexto são passados ​​para este arquivo através de sys.argv[1].

Acho que você gosta

Origin blog.csdn.net/bill_love_c/article/details/130567372
Recomendado
Clasificación