摆脱 PyCharm 对 Python static/class 属性 的警告
Getting rid of PyCharm warning for Python static/class property
在我的 Python 2.7 程序中(抱歉,我们有一个第三方预编译的 Python 模块卡在 2.7,是的,我们依靠他们升级,是的,他们是计划到达那里),而不是只有 return True
或 False
:
的功能
foo = self.first_thing()
if not foo:
return False
bar = self.second_thing()
if not bar:
return False
else:
return True
我想让调用者能够记录有关失败的详细信息。所以我创建了一个 'Result' class:
class Result(object):
def __init__(self, success, details):
self.success = success
self.details = details
def __nonzero__(self):
return self.success
现在我可以 return 记录信息:
foo = self.first_thing()
if not foo:
return Result(False, "first_thing failed")
bar = self.second_thing()
if not bar:
return Result(False, "second_thing failed")
else:
return Result(True, "")
这一切都很好。
但现在我注意到每个函数都至少构造了一个令人满意的 Result
值。所以我想提高效率,只创建一个可以随处使用的:
class Result(object):
def __init__(self, success, details):
self.success = success
self.details = details
Result.Success = Result(True, "")
这很好,按预期工作:
foo = self.first_thing()
if not foo:
return Result(False, "first_thing failed")
bar = self.second_thing()
if not bar:
return Result(False, "second_thing failed")
else:
return Result.Success
但是PyCharm不觉得好笑。我有这个的每个地方,PyCharm 都会给我警告 "Unresolved attribute reference 'Success' for class 'Result'"
.
有没有办法让 PyCharm 开心?
您可能希望为默认 'Success' 结果创建一个单独的预定义子 class 结果。
(我一开始误解了你的问题;万一有人发现这个问题并且 只是在寻找一种方法来禁用本地或全局的 PyCharm 检查;向下滚动 ).
例如:
class Result(object):
def __init__(self, success: bool,
details: str):
self.success = success
self.details = details
class ResultSuccess(Result):
def __init__(self, success=True,
details=''):
super(Result, self).__init__(success,
details)
foo = some_class.first_thing()
if not foo:
return Result(False, "first_thing failed")
bar = some_class.second_thing()
if bar:
return ResultSuccess()
else:
return Result(False, "second_thing failed")
请注意,要在 Python 2.7 中使用它,您需要让基础 class 显式继承自 object
,以启用新式 class 功能和 .
在Python3中不需要这个,super(Result, self).__init__(success=True, details='')
可以直接换成super().__init__(success=True, details='')
防止实例化开销
由于涉及范围太广,可能会很快讨论每次实例化新对象的潜在问题,作为对 OP's 评论的回复。
在你走这条路之前,考虑在每次使用时实例化 ResultSuccess
对象是否重要。除非您快速连续地实例化它数千到数十万次,否则我认为它不太可能对大多数用例的性能产生有意义的影响(虽然还没有测试过)。此外,如果对象实例不再used/referenced,则对象实例将被垃圾回收,并且在离开它们使用的范围后不应使用内存。
如果你仍然想这样做,你可以使用一个单独的文件,即你初始化 ResultSuccess
的模块;这也意味着您不必 subclass:
# static_succesresult.py
class Result(object):
def __init__(self, success: bool,
details: str):
self.success = success
self.details = details
ResultSuccess = Result(True, details='')
# elsewhere.py
from static_successresult import ResultSuccess
#logic which uses ResultSuccess
这应该使它成为全球性的。或者,您可以将 ResultSucces
设为 singleton in various ways(如果模块不够用,我喜欢 metaclass 的做法)。但是请注意,这种模式是有争议的。在我看来,它应该谨慎使用,原因超出了这里的范围。我认为对于像这样不应改变状态的小 class 来说很好,但可能有更好的方法来解决这个问题。 (例如,您也可以使用内置的 Enum
,尽管它也使用单例。)
禁用 PyCharm 检查
您可以在设置中全局禁用特定检查。然而,人们通常不想在全球范围内这样做。
这也可以通过放置在本地完成:
# noinspection {particular_inspection_type}
... 在您想禁用它的函数或语句上方。在您的情况下,这将是:
# noinspection PyUnresolvedReferences
def function_example():
return seemingly_unresolved_variable
或
# noinspection PyUnresolvedReferences
statement_example = seemingly_unresolved_variable
幸运的是,PyCharm 可以自动为您执行此操作,因此您不必记住所有检查类型的名称。
在每个文件的基础上禁用检查突出显示:
虽然不是针对特定类型的检查,但也可以针对每个文件禁用检查的突出显示; 'syntax'、'All problems' 和 'None' 是可用的选项。您可以单击右上角的警告符号,然后 select 从下拉菜单中选择所需的选项:
禁用每个语句或函数的检查:
(1) PyCharm 强调具有未解决引用的问题代码:
(2) 打开上下文菜单(默认=alt+enter):
(3) Select 在第二个上下文菜单中禁用检查(对于所需的上下文)。在这种情况下,只能选择 'suppress for statement',因为我们不在函数的上下文中:
(4) 添加了一行 PyCharm 忽略 selected 作用域的检查:
有关详细信息,请参阅 'Disabling and enabling inspections' on Jetbrain's website。
下面是关于抑制 functions/statements 警告的文字描述,以防人们无法看到图像:
当您为带下划线的语句调出上下文菜单时(默认情况下应为 alt+enter,将光标置于有问题的代码处),会弹出更正问题的建议。如果您选择此项,将出现一个新的下拉菜单,要求您更正问题。如果您随后使用向右箭头或单击向右箭头以获得建议的更正,则会出现一个新的下拉菜单,其中包含“抑制语句”或“抑制函数”等选项。
选择适用于您的情况的选项以自动添加一行,指示 linter 应忽略 selected 范围的特定检查。
在你的情况下,这将是:
# noinspection PyUnresolvedReferences
.
我有一段时间没有使用 PyCharm,但我认为添加类型注释可能会起作用:
from typing import ClassVar
class Result(object):
Success: ClassVar['Result']
def __init__(self, success, details):
self.success = success
self.details = details
Result.Success = Result(True, "")
在我的 Python 2.7 程序中(抱歉,我们有一个第三方预编译的 Python 模块卡在 2.7,是的,我们依靠他们升级,是的,他们是计划到达那里),而不是只有 return True
或 False
:
foo = self.first_thing()
if not foo:
return False
bar = self.second_thing()
if not bar:
return False
else:
return True
我想让调用者能够记录有关失败的详细信息。所以我创建了一个 'Result' class:
class Result(object):
def __init__(self, success, details):
self.success = success
self.details = details
def __nonzero__(self):
return self.success
现在我可以 return 记录信息:
foo = self.first_thing()
if not foo:
return Result(False, "first_thing failed")
bar = self.second_thing()
if not bar:
return Result(False, "second_thing failed")
else:
return Result(True, "")
这一切都很好。
但现在我注意到每个函数都至少构造了一个令人满意的 Result
值。所以我想提高效率,只创建一个可以随处使用的:
class Result(object):
def __init__(self, success, details):
self.success = success
self.details = details
Result.Success = Result(True, "")
这很好,按预期工作:
foo = self.first_thing()
if not foo:
return Result(False, "first_thing failed")
bar = self.second_thing()
if not bar:
return Result(False, "second_thing failed")
else:
return Result.Success
但是PyCharm不觉得好笑。我有这个的每个地方,PyCharm 都会给我警告 "Unresolved attribute reference 'Success' for class 'Result'"
.
有没有办法让 PyCharm 开心?
您可能希望为默认 'Success' 结果创建一个单独的预定义子 class 结果。
(我一开始误解了你的问题;万一有人发现这个问题并且 只是在寻找一种方法来禁用本地或全局的 PyCharm 检查;向下滚动 ).
例如:
class Result(object):
def __init__(self, success: bool,
details: str):
self.success = success
self.details = details
class ResultSuccess(Result):
def __init__(self, success=True,
details=''):
super(Result, self).__init__(success,
details)
foo = some_class.first_thing()
if not foo:
return Result(False, "first_thing failed")
bar = some_class.second_thing()
if bar:
return ResultSuccess()
else:
return Result(False, "second_thing failed")
请注意,要在 Python 2.7 中使用它,您需要让基础 class 显式继承自 object
,以启用新式 class 功能和
在Python3中不需要这个,super(Result, self).__init__(success=True, details='')
可以直接换成super().__init__(success=True, details='')
防止实例化开销
由于涉及范围太广,可能会很快讨论每次实例化新对象的潜在问题,作为对 OP's 评论的回复。
在你走这条路之前,考虑在每次使用时实例化 ResultSuccess
对象是否重要。除非您快速连续地实例化它数千到数十万次,否则我认为它不太可能对大多数用例的性能产生有意义的影响(虽然还没有测试过)。此外,如果对象实例不再used/referenced,则对象实例将被垃圾回收,并且在离开它们使用的范围后不应使用内存。
如果你仍然想这样做,你可以使用一个单独的文件,即你初始化 ResultSuccess
的模块;这也意味着您不必 subclass:
# static_succesresult.py
class Result(object):
def __init__(self, success: bool,
details: str):
self.success = success
self.details = details
ResultSuccess = Result(True, details='')
# elsewhere.py
from static_successresult import ResultSuccess
#logic which uses ResultSuccess
这应该使它成为全球性的。或者,您可以将 ResultSucces
设为 singleton in various ways(如果模块不够用,我喜欢 metaclass 的做法)。但是请注意,这种模式是有争议的。在我看来,它应该谨慎使用,原因超出了这里的范围。我认为对于像这样不应改变状态的小 class 来说很好,但可能有更好的方法来解决这个问题。 (例如,您也可以使用内置的 Enum
,尽管它也使用单例。)
禁用 PyCharm 检查
您可以在设置中全局禁用特定检查。然而,人们通常不想在全球范围内这样做。
这也可以通过放置在本地完成:
# noinspection {particular_inspection_type}
... 在您想禁用它的函数或语句上方。在您的情况下,这将是:
# noinspection PyUnresolvedReferences
def function_example():
return seemingly_unresolved_variable
或
# noinspection PyUnresolvedReferences
statement_example = seemingly_unresolved_variable
幸运的是,PyCharm 可以自动为您执行此操作,因此您不必记住所有检查类型的名称。
在每个文件的基础上禁用检查突出显示:
虽然不是针对特定类型的检查,但也可以针对每个文件禁用检查的突出显示; 'syntax'、'All problems' 和 'None' 是可用的选项。您可以单击右上角的警告符号,然后 select 从下拉菜单中选择所需的选项:
禁用每个语句或函数的检查:
(1) PyCharm 强调具有未解决引用的问题代码:
(2) 打开上下文菜单(默认=alt+enter):
(3) Select 在第二个上下文菜单中禁用检查(对于所需的上下文)。在这种情况下,只能选择 'suppress for statement',因为我们不在函数的上下文中:
(4) 添加了一行 PyCharm 忽略 selected 作用域的检查:
有关详细信息,请参阅 'Disabling and enabling inspections' on Jetbrain's website。
下面是关于抑制 functions/statements 警告的文字描述,以防人们无法看到图像:
当您为带下划线的语句调出上下文菜单时(默认情况下应为 alt+enter,将光标置于有问题的代码处),会弹出更正问题的建议。如果您选择此项,将出现一个新的下拉菜单,要求您更正问题。如果您随后使用向右箭头或单击向右箭头以获得建议的更正,则会出现一个新的下拉菜单,其中包含“抑制语句”或“抑制函数”等选项。
选择适用于您的情况的选项以自动添加一行,指示 linter 应忽略 selected 范围的特定检查。
在你的情况下,这将是:
# noinspection PyUnresolvedReferences
.
我有一段时间没有使用 PyCharm,但我认为添加类型注释可能会起作用:
from typing import ClassVar
class Result(object):
Success: ClassVar['Result']
def __init__(self, success, details):
self.success = success
self.details = details
Result.Success = Result(True, "")