方法的装饰符参数不能是基于类的静态成员的列表理解。

问题描述 投票:2回答:1

让我们考虑一下下面的例子。

def dec(arg):
    def wrapper(m):
        def result(self):
            print(arg)
            m(self)
        return result
    return wrapper


class X:

    x = [7]

    @dec(x)
    def f(self):
        print('hello from f')

    @dec([i + 5 for i in x])
    def g(self):
        print('hello from g')


X().f()
X().g()

我的代码可以正常工作 python3.6 安装,但pylint抱怨 undefined-variable x 在装饰者的参数中 g 方法。为什么会出现这种情况?这段代码以这种方式实现是不是一个好主意?如果是--有什么替代方案吗?

python oop decorator pylint
1个回答
3
投票

简答。 这是Pylint 2.4.4(和更老版本)的一个bug。我已经提交了一个补丁幽林特的下一个版本中会收录该作品,该作品已被合并到母版中。

详见 (对于好奇的人来说)。

当Python将代码解析成抽象语法树时 (AST) 节点,装饰器节点(如 @dec...)被连接到 decorator_list 节点的函数定义(例如 def g...):

    stmt = FunctionDef(identifier name, arguments args,
                       stmt* body, expr* decorator_list, expr? returns,
                       string? type_comment)

Pylint有一个函数参数的特殊情况(args),但忘了检查 decorator_listreturns 注解。这导致Pylint错误地将装饰符视为函数内部的装饰符,因此在函数作用域而不是类作用域。

解决方法:

作为一个静态代码检查器,Pylint只能走到这一步。它目前有500个未解决的问题,所以预计会有一些误报。目前,你可以遵循 @chepner'的建议,禁用Pylint警告, 只是为了这一行。

    @dec([i + 5 for i in x]) # pylint: disable=undefined-variable

但我现在就要! (对于那些想在不作弊的情况下获得1010代码等级的人)

git clone https://github.com/PyCQA/astroid.git
git clone https://github.com/PyCQA/pylint.git
pip install ./astroid/
pip install ./pylint/
pylint --version

Pylint 2.5.0-dev1 astroid 2.4.0

使用Pylint的开发版本(和Astroid,Pylint用于解析的库),问题中的代码不应该给出任何 undefined-variable 抱怨(尽管它会给出一些风格警告)。如果有变化,请重新打开bug报告!

© www.soinside.com 2019 - 2024. All rights reserved.