【问题标题】:Pylint throws not-callable on decorator defined within classPylint 在类中定义的装饰器上抛出不可调用
【发布时间】:2021-11-09 11:23:15
【问题描述】:

我正在尝试创建一个具有剩余时间属性的类,并在其中执行函数可以减少此时间。这是代码

class TestClass:
    def __init__(self):
        self.time_remaining = 240

    @staticmethod
    def time_taken(start):
        return (datetime.now() - start).seconds

    def with_timeout(f):
        @wraps(f)
        def wrapper(self, *args, **kwargs):
            start = datetime.now()
            result = f(self, *args, **kwargs)
            self.time_remaining = (
                self.time_remaining - TestClass.time_taken(start)
            )
            return result

        return wrapper

    @with_timeout
    def do_something(self, param):
        # DO Something

然后当我实例化类并像这样使用do_something 时:

test_class = TestClass()
test_class.do_something("param")

它按预期工作。但是,当我在代码上运行 pylint 时出现错误:

pylint: not-callable / f is not callable

这是误报还是有更好的方法来编写此功能?

谢谢

【问题讨论】:

  • with_timeout 被定义为类的常规方法,linter 认为 f 将是实例(self)。尝试将其更改为静态方法或将其移出类?
  • 是的,我可以看到这一点,但不确定如何解决。通过使用@staticmethod,我得到TypeError: 'staticmethod' object is not callable 的运行时错误。如果我要把它移到课堂外,我怎么能控制 self 参数?
  • 在包装中?如果 linter 将该参数作为实例拾取,我会感到惊讶,因为它实际上不是普通的实例方法
  • 应该将函数移到类之外——它不是方法,也不能用作staticmethod。对于内部的wrapper,装饰器的定义位置并不重要。
  • self 的绑定取决于方法的调用方式,而不是定义的位置。将def with_timeout 移出类主体不会改变wrapper 的工作方式。

标签: python class decorator pylint callable


【解决方案1】:

感谢 cmets。将方法移到类之外是必需的,因为 self 取决于方法的调用方式,而不是它的定义位置,因此不需要在类中定义装饰器即可访问 self:

def time_taken(start):
    return (datetime.now() - start).seconds

def with_timeout(f):
    @wraps(f)
    def wrapper(self, *args, **kwargs):
        start = datetime.now()
        result = f(self, *args, **kwargs)
        self.time_remaining = self.time_remaining - time_taken(start)
        return result

    return wrapper


class TestClass:
    def __init__(self):
        self.time_remaining = 240

    @with_timeout
    def do_something(self, param):
        # DO Something

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-02
    • 1970-01-01
    • 2020-02-26
    • 1970-01-01
    • 2015-10-23
    • 1970-01-01
    相关资源
    最近更新 更多