首页 > 解决方案 > 尝试将一个函数的输出传递给另一个函数时出现 TypeError

问题描述

我正在尝试用python制作一个聊天室/短信工具。我需要使用.connect() method. 每次我去我家外面的某个地方并连接到 wifi 时,我的私人 IP 地址都会改变,所以我希望我的代码通过传递os.system("ipconfig getifaddr <wireless interface>")给该.connect()方法来适应这种情况。

我在运行我的代码后发现这是不正确的,这引发了 TypeError。我知道这是不正确的,因为该os.system()函数已执行并将我的 IP 地址打印到控制台,而不是将该输出传递给该函数。我假设函数返回 0 给函数,表明命令没有出错,这不是我的本意。我希望将 IP 地址传递给函数。

它有点类似于 bash,像这样:ipconfig getifaddr <wireless interface> > file.txt命令的输出被重定向到一个名为file.txt

这是我的代码:

客户端.py

import socket
import threading
import subprocess

nickname = input("Choose a nickname: ")
subprocess.run("./ipaddress.sh")

with open("ip_addr.txt", 'r') as f:
    file = f.readline()

client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client.connect((file, 48812))

def receive():
    while True:
        try:
            message = client.recv(1024).decode('ascii')
            if message == 'NICK':
                pass
            else:
                print(message)

        except:
            print("An error occurred!")
            client.close()
            break


def write():
    while True:
        message = f'{nickname}: {input("")}'
        client.send(message.encode('ascii'))


receive_thread = threading.Thread(target=receive)
receive_thread.start()

write_thread = threading.Thread(target=write)
write_thread.start()

我不知道我是否还必须在服务器文件中进行更改,但如果我这样做,您也可以看到以下代码:

服务器.py

import threading
import socket
import subprocess

subprocess.run("./ipaddress.sh")

with open("ip_addr.txt", 'r') as f:
    file = f.readline()

host = file
port = 48812

server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind((host, port))
server.listen()

clients = []
nicknames = []

def broadcast(message):
    for client in clients:
        client.send(message)

def handle(client):
    while True:
        try:
            message = client.recv(1024)
            broadcast(message)

        except:
            index = clients.index(client)
            clients.remove(client)
            client.close()
            nickname = nicknames[index]
            broadcast(f"{nickname} left the chat".encode('ascii'))
            nicknames.remove(nickname)
            break
def receive():
    while True:
        client, address = server.accept()
        print(f"Connected with{str(address)}")

        client.send("NICK".encode("ascii"))
        nickname = client.recv(1024).decode('ascii')
        nicknames.append(nickname)
        clients.append(client)

        print(f"Nickname of client is {nickname}\n")
        broadcast(f'{nickname}joined the chat!\n'.encode('ascii'))
        client.send("Connected to the server!\n".encode('ascii'))

        thread = threading.Thread(target=handle, args=(client,))
        thread.start()


print("Server is listening...")
receive()

这是完整的回溯:

Traceback (most recent call last):
  File "/Users/matthewschell/PycharmProjects/TCP Chat Room/server.py", line 14, in <module>
    server.bind((host, port))
socket.gaierror: [Errno 8] nodename nor servname provided, or not known

编辑:我没有像其他人不推荐的那样使用os.system(),而是使用了 subprocess 。它修复了引发的异常,os.system()但现在引发了另一个异常。请参阅上面的完整回溯。另请参阅上面的编辑代码。请注意打开由 bash 脚本创建的文件的新with语句,该文件包含两个文件中的 ip 地址。

标签: pythonpython-3.xsocketstypeerror

解决方案


您的猜测是正确的 os.system() 返回子进程的退出代码,它是一个整数(0 表示成功)。您正在寻找的是来自子进程的标准输出,而获得它的最佳方法是使用 Python“子进程”模块而不是 os.system。

>>> outcome = subprocess.run('/bin/date', capture_output=True)
>>> outcome.returncode
0
>>> outcome.stdout
b'Thu 11 Feb 2021 18:30:57 GMT\n'
>>>

推荐阅读