繁体   English   中英

使用装饰器将 class 外部的方法包装在 Python 中

[英]Wrapping a method from outside the class in Python with decorator

我想问一个问题,我如何覆盖/扩展现有的外部 python class。我希望能够像父 class 一样调用相同的 API,但进行一些修改。

像这样的东西:

[a]
b = 1
import configparser

# my wrapper class
class MyConfigParser(configparser.ConfigParser):
    # override/wrap the parent class with all arguments (could be some optionals too) parent function has the same name, but it shouldn't be called
    def getint(self, section, option):
        # call the parent function, pass all args (maybe without mentioning them, ideally without copying them)
        ret = parent.get(section, option)
        # make modifications
        print("my wrapper")
        ret = ret + 1
        # return modified value
        return ret

config = MyConfigParser()
# call parent function
config.read('my-file.ini')
# call my wrapped-function
a = config.getint('a','b')

仅供参考,我无法修改父 class。该怎么做?

我认为您对 装饰器是什么以及单词环绕通常指的是什么感到困惑。 如果我正确理解您的意图,这些都不适用于此处。

当然,您可以将一些现有的 class 子类化,您可能会或可能不会控制并覆盖其方法。 当然,您可以方便地从您自己的方法中调用父类的方法。 在 Python 中,您通常为此使用内置的super代理 class。 但这一切都与装饰或包装无关。

如果你想覆盖超类的方法,你应该注意匹配它的签名。 否则你会违反类型安全。 如果您只关心一些特定的 arguments 但不是全部,您可以稍微作弊并在包罗万象的*args, **kwargs参数中收集 rest,但您应该将它们传递给超类的方法称呼。

此外,您似乎在覆盖的getint方法中调用了ConfigParser.get方法。 但我很确定这是一个打字错误/错误,因为您显然期望分配给ret的返回值是int ,而get返回str 所以你应该在那里调用super().getint(...)

最后,如果我们已经这样做了,那么用类型正确注释您的函数是一种很好的形式。 (详见PEP 484

这是我认为你需要的:

from configparser import ConfigParser
from typing import Any


class MyConfigParser(ConfigParser):
    def getint(self, section: str, option: str, *args: Any, **kwargs: Any) -> int:
        ret = super().getint(section, option, *args, **kwargs)
        print("overridden `getint`")
        ret += 1
        return ret  # type: ignore[no-any-return]


if __name__ == "__main__":
    config = MyConfigParser()
    config.read("my-file.ini")
    print(config.getint("a", "b"))

带有示例ini文件的 output:

overridden `getint`
2

这个平台上有很多关于supersubclassing以及decorators的问答。 我建议您搜索一下并阅读这些内容。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM