【发布时间】:2021-09-28 13:15:13
【问题描述】:
问题描述
考虑以下场景:
- 我有一个能够发表演讲的“演讲者”课程。
- 一些方法,例如“说”,有效地发表演讲。
- 发表演讲前,我们需要打开麦克风,演讲结束后,我们需要关闭。
- 为了避免在每一种传递演讲的方法中都这样做,我创建了一个装饰器来打开和关闭麦克风。
这是一个虚构的例子。我真正的代码是关于连接和断开数据库。
代码:
def use_mic(method):
def wrapper(self, *args, **kwargs): # [3]
self.turn_on_mic() # [2] Method "turn_on_mic" is called, it is not a method of "str"
method(self, *args, **kwargs)
self.turn_off_mic() # [2]
return wrapper
class Speaker:
def __init__(self, name):
self.name = name
self.mic_on = False
@use_mic
def speak(self, message):
print("[%s speaks] %s" % (self.name, message))
def turn_on_mic(self):
print("Turn on microphone")
self.mic_on = True
def turn_off_mic(self):
print("Turn off microphone")
self.mic_on = False
def greet(self):
self.speak('Good morning my neighbours') # [1] Lint warning here, because [2]
john = Speaker('John')
john.greet()
代码运行正常,但 PyCharm 报告以下 lint 警告:
PyCharm 显然将 [1] 处传递的 str 参数视为 [3] 处的第一个参数“self”,并根据 [2] 警告“没有此类属性”。但是“Python 在使用
我的问题
- 为什么 PyCharm 会误解代码?
- 是 PyCharm 默认 lint 工具的 bug,还是我写了非 Python 代码?
- 编写此类代码的 Python 方式是什么?
- 当我将 [3] 更改为以下代码时,警告消失了,但它是 python 的方式吗?
代码:
def wrapper(*args, **kwargs): # [2]
self = args[0]
我正在使用 PyCharm 2021.1.3(社区版)和 Python 3.7.5
【问题讨论】:
-
这不仅仅是警告,这是错误而且我认为你甚至不能运行该代码,因为
wrapper至少需要一个参数self,所以@ 987654327@ 将是空的,因为self.speak('Good morning my neighbours')和method(*args, **kwargs)将抛出错误,指出位置message参数丢失,因为它已被用作包装器的self,但def speak(self, message)期望它。 -
“代码运行正常”——不,不,它没有。我在 Python 3.9 上运行它,我得到“TypeError: speak() missing 1 required positional argument: 'message'”。你需要
method(self, *args, **kwargs)才能工作。 -
@ThePyGuy 对不起,我弄错了,调用方法时添加“self”
-
@AKX 对不起,我弄错了,调用方法的时候加上“self”
-
无论你的代码是否是“pythonic”,这看起来像是 PyCharm 中的一个错误。您是否尝试向 JetBrains 报告此问题?至于为什么,没有考虑到错误。
标签: python pycharm decorator lint