首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >将python 2代码转换为python 3

将python 2代码转换为python 3
EN

Stack Overflow用户
提问于 2017-03-17 09:16:17
回答 4查看 3.6K关注 0票数 3

我正在尝试将下面用python 2编写的代码转换为python 3,这个python代码负责TCP端口转发。它来自于这个页面:http://code.activestate.com/recipes/483730-port-forwarding/

代码语言:javascript
复制
import socket
import sys
import thread

def main(setup, error):
    sys.stderr = file(error, 'a')
    for settings in parse(setup):
        thread.start_new_thread(server, settings)
    lock = thread.allocate_lock()
    lock.acquire()
    lock.acquire()

def parse(setup):
    settings = list()
    for line in file(setup):
        parts = line.split()
        settings.append((parts[0], int(parts[1]), int(parts[2])))
    return settings

def server(*settings):
    try:
        dock_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        dock_socket.bind(('', settings[2]))
        dock_socket.listen(5)
        while True:
            client_socket = dock_socket.accept()[0]
            server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            server_socket.connect((settings[0], settings[1]))
            thread.start_new_thread(forward, (client_socket, server_socket))
            thread.start_new_thread(forward, (server_socket, client_socket))
    finally:
        thread.start_new_thread(server, settings)

def forward(source, destination):
    string = ' '
    while string:
        string = source.recv(1024)
        if string:
            destination.sendall(string)
        else:
            source.shutdown(socket.SHUT_RD)
            destination.shutdown(socket.SHUT_WR)

if __name__ == '__main__':
    main('proxy.ini', 'error.log')

以下是我所拥有的:

代码语言:javascript
复制
import socket
import sys
import threading
import time

def main(setup, error):
    # open file for error messages
    sys.stderr = open(error, 'a')
    # read settings for port forwarding

    threads = []

    for settings in parse(setup):
        #thread.start_new_thread(server, settings)
        t = threading.Thread(target=server, args=(settings))
        t.start()
        threads.append(t)

    for t in threads:
        t.join()

    # wait for <ctrl-c>
    while True:
        time.sleep(60)

def parse(setup):
    settings = list()
    file = open(setup)

    for line in iter(file):
        parts = line.split()
        settings.append((int(parts[0]), parts[1], int(parts[2])))

    return settings

def server(*settings):

    try:
        dock_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        dock_socket.bind(('', settings[0]))
        dock_socket.listen(5)
        while True:
            client_socket = dock_socket.accept()[0]
            server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            server_socket.connect((settings[1], settings[2]))

            Thread1 = threading.Thread(target=forward, args=(client_socket, server_socket))
            Thread1.start()

            Thread2 = threading.Thread(target=forward, args=(server_socket, client_socket))
            Thread2.start()

    finally:
        thread = threading.Thread(targer=server, args=settings)
        thread.start()

def forward(source, destination):
    string = ' '
    while string:
        string = source.recv(1024)
        if string:
            destination.sendall(string)
        else:
            source.shutdown(socket.SHUT_RD)
            destination.shutdown(socket.SHUT_WR)

if __name__ == '__main__':
    main('port-forward.config', 'error.log')

python 3版本看起来确实有效。但我不能完全确定它是否写得正确。我不清楚代码的线程部分。python 2版本使用线程模块,python 3版本使用线程模块。查看python 2版本,它在主函数中使用锁。我需要在python 3版本中使用锁吗?另一个问题是,是否应该在python 3代码中将两个线程(线程1和线程2)连接到服务器函数中?

与python版本无关的另一个问题是服务器函数的参数。我知道“设置”变量指的是一个列表。为什么在“设置”参数之前需要有一个星号?我看了一下pythonDocumentshttps://docs.python.org/3/tutorial/controlflow.html#arbitrary-argument-lists中的下面一页

但我不明白为什么在没有星号的情况下传递设置列表不起作用。

另一个问题是关于python 2代码中的线程锁。为什么锁被买了两次?我试着移除其中一个锁,程序在启动后立即结束。

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2017-03-17 09:32:13

通过使用命令行工具2to3将代码转换为Python3,您可以节省一些工作,如(从bashbash命令行):

代码语言:javascript
复制
2to3 -w myscript.py

但让我们回答你的实际问题:为什么定义中的星星

代码语言:javascript
复制
def server(*settings):
    ...

函数thread.start_new_thread实际上将启动server()函数,如下所示:

代码语言:javascript
复制
server(arg1, arg2, arg3)

其中arg1arg2等来自于start_new_thread的第二个论点。声明def server(*settings)将这些参数收集回一个名为settings的列表中,您的函数将继续使用该列表。如果您编写了def server(settings) (没有星号),您的函数将被声明为接受一个参数,但将使用多个参数进行调用。

票数 5
EN

Stack Overflow用户

发布于 2017-03-17 09:24:50

您可以使用python 3附带的2到3工具作为标准模块。它为你完成了大部分的转换。

代码语言:javascript
复制
$2to3 youpythonfile.py

您可以在python 3中使用_thread模块,这与python 2中的thread相同。

票数 3
EN

Stack Overflow用户

发布于 2017-03-17 09:21:30

您可以使用未来主义脚本将py2代码转换为py3

参见:http://python-future.org/quickstart.html#quick-start-guide用于安装,http://python-future.org/quickstart.html#to-convert-existing-python-2-code为例

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/42853409

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档