Python 为什么在这些修饰的方法中有警告?

Python 为什么在这些修饰的方法中有警告?,python,python-3.x,pycharm,python-decorators,Python,Python 3.x,Pycharm,Python Decorators,我喜欢使用装饰器,我的第一个用途是包装一个HTTP调用来解释失败的连接。工作守则如下: import requests class Gotify: def __init__(self): self.url = "https://postman-echo.com/status/200" def ensure_safe_call(caller): def wrapper(*args, **kwargs):

我喜欢使用装饰器,我的第一个用途是包装一个HTTP调用来解释失败的连接。工作守则如下:

import requests

class Gotify:
    def __init__(self):
        self.url = "https://postman-echo.com/status/200"

    def ensure_safe_call(caller):
        def wrapper(*args, **kwargs):
            try:
                r = caller(*args, **kwargs)
                r.raise_for_status()
            except Exception as e:
                try:
                    print(f"cannot reach gotify: {e}: {r.text}")
                except NameError:
                    print(f"cannot reach gotify: {e} (the response r does not exist)")
            else:
                print("OK notified gotify of result change")

        return wrapper

    @ensure_safe_call
    def send(self, title, message):
        return requests.get(self.url)

Gotify().send("hello", "world")
此正确选项显示结果更改通知gotify的
OK

在PyCharm中编辑此内容时,我收到两条我不理解的警告:

在我的decorators上下文中,它们是什么意思(如果我不使用decorators,就没有了)

classgotify:
定义初始化(自):
self.url=”https://postman-echo.com/status/200"
def确保安全呼叫(呼叫方):
因为
sure\u safe\u call
是一个类方法,所以第一个参数(在您的例子中是
caller
)实际上是
self
参数,即clas对象--
Gotify
的实例

因此,出现了关于
Gotify
对象不可调用的警告消息(它不可调用,因为您没有在
Gotify
类中重写
\u调用\u
类方法)

函数sure\u safe\u调用缺少位置参数
——这是因为
sure\u safe\u调用
只接受
self
参数,并且不指定任何实际的输入参数(请记住,
调用方==self
以您定义它的方式)。因此,您的decorator
确保\u safe\u调用
无法包装任何内容,因为它不接受任何位置参数

您需要定义一个位置参数

def确保安全呼叫(self,caller):
...
class Gotify:
定义初始化(自):
self.url=”https://postman-echo.com/status/200"
def确保安全呼叫(呼叫方):
因为
sure\u safe\u call
是一个类方法,所以第一个参数(在您的例子中是
caller
)实际上是
self
参数,即clas对象--
Gotify
的实例

因此,出现了关于
Gotify
对象不可调用的警告消息(它不可调用,因为您没有在
Gotify
类中重写
\u调用\u
类方法)

函数sure\u safe\u调用缺少位置参数
——这是因为
sure\u safe\u调用
只接受
self
参数,并且不指定任何实际的输入参数(请记住,
调用方==self
以您定义它的方式)。因此,您的decorator
确保\u safe\u调用
无法包装任何内容,因为它不接受任何位置参数

您需要定义一个位置参数

def确保安全呼叫(self,caller):
...

这个问题在这里已经有了答案:这个问题在这里已经有了答案:当你说“不能包装任何东西”时,你的意思是代码错了?我很惊讶,因为它的行为正确(对于
https://postman-echo.com/status/200
https://postman-echo.com/status/400
,它涵盖了两种情况(打印和提升),即“不能包装任何内容”,我的意思是您不能使用该功能装饰另一个功能。您修饰的函数作为位置参数传递给修饰函数--
确保\u safe\u call
是类函数,因此隐式传递给它的第一个参数是对象的实例(通常称为“self”)--在您的例子中,它被称为
调用者
。您需要将另一个参数添加到
确保安全\u调用
,第二个参数将是修饰的函数<代码>def确保安全呼叫(self,caller):感谢您的解释。我尝试了您的解决方案,I)警告消失,但ii)代码不再工作:)(
TypeError:sure\u safe\u call()缺少1个必需的位置参数:“caller”
)。不过,我在示例中的代码确实有效。所以我很困惑,尤其是你明确指出了一点。好吧,为了避免这个问题,你应该让
确保\u afe\u call
成为一个静态函数(将它带到课堂之外)。它的编写方式是一个静态函数——将它移出类并保留签名
确保安全\u调用(调用者)
将为您提供所需的结果。根据我的经验,我以前从未见过作为类函数的装饰器。我只把它们看作是静态函数当你说“不能包装任何东西”时,你的意思是代码错了?我很惊讶,因为它的行为正确(对于
https://postman-echo.com/status/200
https://postman-echo.com/status/400
,它涵盖了两种情况(打印和提升),即“不能包装任何内容”,我的意思是您不能使用该功能装饰另一个功能。您修饰的函数作为位置参数传递给修饰函数--
确保\u safe\u call
是类函数,因此隐式传递给它的第一个参数是对象的实例(通常称为“self”)--在您的例子中,它被称为
调用者
。您需要将另一个参数添加到
确保安全\u调用
,第二个参数将是修饰的函数<代码>def确保安全呼叫(self,caller):感谢您的解释。我尝试了您的解决方案,I)警告消失,但ii)代码不再工作:)(
TypeError:sure\u safe\u call()缺少1个必需的位置参数:“caller”
)。不过,我在示例中的代码确实有效。所以我很困惑,尤其是你明确指出了一点。好吧,为了避免这个问题,你应该让
确保\u afe\u call
成为一个静态函数(将它带到课堂之外)。它的编写方式是一个静态函数——将它移出类并保留签名
确保安全\u调用(调用者)
将为您提供所需的结果。根据我的经验,我以前从未见过作为类函数的装饰器。我只把它们看作是静态函数