python - 我的异步装饰器不断返回NoneType错误

标签 python sockets python-asyncio

我正在尝试在树莓派上编写套接字服务器代码。我正在尝试使用装饰器将客户端连接到服务器(这将是我的树莓派)。但是我的代码不断抛出NoneType错误。我对异步装饰器有些陌生,需要一些帮助。您能否看到我的错误出处,请更正我的代码?我将在下面列出我的代码和错误消息。
我的错误讯息:

C:\Users\####\AppData\Local\Programs\Python\Python36-32\python.exe C:/Users/#####/Desktop/autorank/server/client.py
Traceback (most recent call last):
  File "C:/Users/#####/Desktop/autorank/server/client.py", line 5, in <module>
    @client.connection(("192.168.0.11", 56500))
TypeError: 'NoneType' object is not callable
我的客户代码包:
import socket, asyncio

class Client:
    def __init__(self):
        self.s = None
        self.data = None

    def connection(self, addr):
        """An asynchronous decorator for any server mainloop. Just decorate it with this and add a Client parameter."""

        def wrapper1(func):
            async def wrapper2(*args):
                self.connect(addr)
                await func(self)
                self.close_conn()
                return await func(self)
            return wrapper2

    async def connect(self, addr):
        """Connects to the desired server. You can make a server mainloop with the connection decorator."""

        self.s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.s.connect(addr)

        self.addr = addr

        print(f"Connected to {addr}")

    async def close_conn(self):
        """Closes connection with the address connected to."""

        self.s.close()

        print(f"Disconnected from {self.addr}")
        del self.addr

    async def send_bytes(self, bytes_data):
        """Sends bytedata through a pipe to connected address"""

        self.s.sendall(bytes_data)

        print(f"Sent {bytes_data.decode()} in bytedata format to {self.addr}")

    async def recv(self, buf_size):
        """Recieves data from a server in bytedata format"""

        self.data = self.s.recv(buf_size)
最后,我的main.py:
import asyncserver

client = asyncserver.Client()

@client.connection(("192.168.0.11", 56500))
def mainloop(cli):
    cli.send_bytes(b'Hello!!')
    cli.recv(1024)
    print(cli.data.decode())
请说我是否应该改善我的问题,我们将不胜感激!

最佳答案

connection装饰器正确定义了wrapper1,但未能返回它。它隐式返回None,这就是在顶层用作mainloop的结果,从而导致错误。
请注意,wrapper2等待func(self),这可能会导致另一个错误,即None无法等待。如果计划等待装饰的函数,则应使其异步(async def mainloop(cli): ...)或使其返回等待对象。
最后,wrapper2如果不使用任意*args,则不应接受。这将导致像mainloop(1, 2, 3)之类的东西在忽略参数的情况下似乎可以正常工作。通常,接受*args的包装器的目的是将它们转发给包装的函数。如果您不想要或不需要它,只需使wrapper2不接受任何参数即可。

关于python - 我的异步装饰器不断返回NoneType错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65365353/

相关文章:

python - 如何在 Here Document 之后给出参数?

python - 向 Django 模型添加代码和方法会破坏它

python - 颜色空间映射 YCbCr 到 RGB

sockets - 数据包与 TCP 选择性确认的交互如何工作?

python - 为什么 python 的 ipv6 连接失败?

python - 为什么我在 mypy 中使用 await 表达式得到无效语法?

python - TypeError : An asyncio. Future,需要协程或等待

python - Windows 客户端和 Linux 服务器之间的通信

python - 异步协程上的高阶函数

c# - 套接字问题,客户端声称连接失败,但服务器说连接成功