带有 self 参数的 Python 装饰器:类型错误:函数需要 2 个位置参数,但给出了 1 个

问题描述 投票:0回答:1

我正在使用一个简单的函数来返回存储在变量

self._time
中的ntp时间。每次调用此函数时,我想发送一个新的 ntp 请求来更新时间,然后再由函数返回时间(还有其他函数也需要查询 ntp 时间)。我决定为此使用装饰器。函数调用如下所示:

@_get_time_from_server
def _get_ntp_time(self) -> tuple:
    # Returns ntp time from ntp server.
    return self._time

装饰器函数看起来像这样:

def _get_time_from_server(self, func):
    # Tries got receive the time from the ntp server.
    # On success, func() will be called.
    # Otherwise, the operation will be aborted.
    # This is a decorator function.
    def wrapper(*args, **kwargs):
        if self._wifi.is_enabled():
            self._wifi.connect_to_ap()
            # Check if we are connected.
            if self._wifi.is_connected_to_ap():
                # Query NTP Server.
                log.info('Querying NTP Server.')
                res = self._query_server()
                if res:
                    return func(self, *args, **kwargs)
                else:
                    log.warning('Could not retrieve time from NTP server.')
                    return
            return
       return
    return wrapper

拨打

self._query_server()
将会更新
self._time

当我调用

_get_ntp_time()
函数时,我收到以下错误消息:

TypeError:函数需要 2 个位置参数,但给出了 1 个

我并没有真正找到很多在装饰器函数中使用 self 参数的示例。但我需要这样做,因为我正在访问一些实例属性。我尝试了 self 参数,但没有找到任何解决方案。

我找到了这篇文章但无法解决我的问题。

我是装饰器函数的新手,但它似乎对我来说是一个合适的用例。我做错了什么吗?

堆栈跟踪:

Traceback (most recent call last):
File "main.py", line 28, in <module>
File "timing.py", line 49, in <module>
File "timing.py", line 117, in Timing
TypeError: function takes 2 positional arguments but 1 were given
MicroPython v1.19.1-932-g6bb60745b on 2023-03-07; ESP32S3 module (spiram) with ESP32S3

第 117 行是“@_get_time_from_server”

python python-decorators
1个回答
0
投票
@decorator
def foo(self):
   return self.a+1

基本相同
foo = decorator(lambda self.a: self.a+1)

你的装饰器只会将函数作为其唯一的参数(站点注释:还有其他方法来定义可以获取多个参数的装饰器)

def _get_time_from_server(func): # only function as parameter
    # Tries got receive the time from the ntp server.
    # On success, func() will be called.
    # Otherwise, the operation will be aborted.
    # This is a decorator function.
    def wrapper(self, *args, **kwargs): # <--- here self is passed
        if self._wifi.is_enabled():
            self._wifi.connect_to_ap()
            # Check if we are connected.
            if self._wifi.is_connected_to_ap():
                # Query NTP Server.
                log.info('Querying NTP Server.')
                res = self._query_server()
                if res:
                    return func(self, *args, **kwargs)
                else:
                    log.warning('Could not retrieve time from NTP server.')
                    return
            return
        return
    return wrapper
© www.soinside.com 2019 - 2024. All rights reserved.