首页 > 解决方案 > 摆脱 Python 静态/类属性的 PyCharm 警告

问题描述

在我的 Python 2.7 程序中(抱歉,我们有一个第三方预编译的 Python 模块,它停留在 2.7,是的,我们依靠他们升级,是的,他们正计划到达那里),而不是让函数只返回TrueFalse

foo = self.first_thing()
if not foo:
   return False
bar = self.second_thing()
if not bar:
   return False
else:
   return True

我想让调用者能够记录有关失败详细信息的信息。所以我创建了一个“结果”类:

class Result(object):
   def __init__(self, success, details):
      self.success = success
      self.details = details

   def __nonzero__(self):
      return self.success

现在我可以返回要记录的信息:

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'"

有没有办法让 PyC​​harm 开心呢?

标签: pythonpycharm

解决方案


您可能希望为默认的“成功”结果创建单独的预定义子类。

(我一开始误解了你的问题;如果有人发现这个问题并且只是在寻找一种在本地或全局禁用 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 中工作,您需要让基类显式继承自object,以启用新型类功能并允许使用super().

在 Python 3 中,这不是必需的,super(Result, self).__init__(success=True, details='')可以替换为super().__init__(success=True, details='')

防止实例化开销

冒着解决范围太广的风险,作为对OP评论的回复,我们很快讨论了每次实例化新对象的潜在问题。

在你走这条路之前,请考虑ResultSuccess在每次使用时实例化对象是否重要。除非您快速连续地实例化它数千到数十万次,否则我认为它不太可能对大多数用例的性能产生有意义的影响(尽管尚未对其进行测试)。此外,如果不再使用/引用对象实例,将被垃圾回收,并且在离开它们的使用范围后不应使用内存。

如果你想这样做,你可以使用一个单独的文件,即你初始化的模块ResultSuccess;这也意味着您不必子类化:

# 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(如果模块不够用,我喜欢元类的做法)。但是请注意,这种模式是有争议的。在我看来,应该小心使用它,原因不在此范围内。我认为对于像这样不应该改变状态的小班来说这很好,但可能有更好的方法来解决这个问题。(例如,您也可以使用内置的,尽管它也使用单例。)。Enum

   

禁用 PyCharm 检查

您可以在设置中全局禁用特定检查。然而,通常人们不想在全球范围内这样做。

这也可以通过放置在本地完成:

# noinspection {particular_inspection_type}

...在您想要禁用它的函数或语句上方。在您的情况下,这将是:

# noinspection PyUnresolvedReferences
def function_example():
    return seemingly_unresolved_variable

或者

# noinspection PyUnresolvedReferences
statement_example = seemingly_unresolved_variable

幸运的是,PyCharm 可以自动为您完成这项工作,因此您不必记住所有检查类型的名称。

在每个文件的基础上禁用检查突出显示:

也可以在每个文件的基础上禁用检查的突出显示,尽管不是针对特定类型的检查;“语法”、“所有问题”和“无”是可用选项。您可以单击右上角的警告符号,然后从下拉菜单中选择所需的选项:

右上角的上下文菜单允许为当前文件选择问题突出显示的程度

禁用每个语句或函数的检查:

(1) PyCharm 强调了有问题的代码有一个未解决的引用: PyCharm 强调了有问题的代码有一个未解决的引用

(2) 打开上下文菜单(默认=alt+enter): 打开上下文菜单(默认=alt+enter)

(3) 在第二个上下文菜单中选择禁用检查(针对所需上下文)。在这种情况下,只能选择“抑制语句”,因为我们不在函数的上下文中:

在第二个上下文菜单中选择禁用检查(对于所需的上下文)

(4) 添加一行让 PyC​​harm 忽略对选定范围的检查:

添加了一行,这将使 PyCharm 忽略对选定范围的检查。

有关详细信息,请参阅Jetbrain 网站上的“禁用和启用检查”

下面是一个文本描述,用于在阻止查看图像的情况下抑制函数/语句的警告:

当您为带下划线的语句调出上下文菜单时(默认情况下应该是 alt+enter,将光标放在有问题的代码上),会弹出更正问题的建议。如果您选择此选项,则会出现一个新的下拉菜单,要求您更正问题。如果您随后使用右箭头或单击右箭头进行建议的更正,则会出现一个新的下拉菜单,其中包含“抑制声明”或“抑制功能”等选项。

选择适用于您的案例的选项以自动添加一行,指示 linter 应忽略所选范围的特定检查。

在您的情况下,这将是:

# noinspection PyUnresolvedReferences.


推荐阅读