我的课堂装饰器在使用皮棉纸警告时是否不够Pythonic或PyCharm还不够聪明?

时间:2018-07-10 08:03:07

标签: python pycharm decorator static-analysis lint

我想在一个类中定义一个装饰器。我不想将其定义为单独的独立函数,因为此装饰器专门用于此类,所以我想将相关方法保持在一起。

此装饰器的目的是检查某些先决条件,尤其是由成员变量保存的数据库连接,SSH连接等仍然可用。如果没有,则装饰函数将不会被调用,并且将完成一些错误报告和清理工作。

我制作了以下测试类来测试它是否有效,并且代码运行良好。但是我发现PyCharm对这段代码显示警告。所以我想知道这是否意味着我的代码不是Python语言,或者PyCharm不够聪明,并错误地发出了此警告?

如果我的代码不是Pythonic,如何更改? 如果是PyCharm的错误,我和我的团队应如何配置PyCharm以使其在保留大多数其他皮棉检查的同时专门忽略这种警告?

class TestClass:
    def __init__(self):
        self.flag = True

    def dec(func):
        def wrapper(self, *args, **kwargs):
            if not self.flag:
                print("Won't run!")
                return empty_fun(self, *args, **kwargs)
            return func(self, *args, **kwargs)

        def empty_fun(*args, **kwargs):
            return None

        return wrapper

    @dec
    def foo(self):
        print("foo")

    @dec
    def bar(self, msg, more, *args, **kwargs):
        print("message: %s" % msg)
        print("more %s:" % more)
        for item in args:
            print("other item: %s" % item)
        name = kwargs.get('name')
        age = kwargs.get('age')
        print('name: %s' % name)
        print('age: %s' % age)


def main():
    t = TestClass()
    t.foo()
    print('-'*10)
    t.bar("abc", 'def', 'hij', 'klm', name='Tom', age=20)


if __name__ == '__main__':
    main()

这是PyCharm报告的皮棉警告:

Lint warning reported by PyCharm

2 个答案:

答案 0 :(得分:3)

您的代码在技术上是正确的(因为它可以按预期工作),但需要注意的是,dec将成为TestClass的方法,并且如果这样调用将被破坏。为避免这种情况,您至少应将其设置为staticmethod

wrt / pythonicity,在不需要此装饰器时,将其作为类的一部分确实是不Python的。它仅适用于此类的事实并不是使其成为该类成员的原因,更不用说使其成为公共API的一部分了。

您可能可以在注释中添加linter提示以使其静音,但是我个人只是从类中提取此装饰器,将其设置为私有,并记录它仅应与该类一起使用。

作为旁注:我假设您的empty_func是“错误报告和清理工作”的占位符-否则它根本就没用-但确实需要在装饰器中定义它吗?

答案 1 :(得分:2)

Python decorator as a staticmethod开始,不鼓励在类中放置装饰器。

想想看,Python提供了这种很好的划分方式,称为 modules 。您是否考虑过将与此类相关的所有代码放在一个模块中,而其他代码放在其他模块中?

  

我强烈建议将装饰器移至模块作用域-它似乎不属于类内部。如果您想将其保留在类中,请不要将其设置为staticmethod,而只需将其del放在类正文的末尾即可–不能在类外使用在这种情况下。