[英]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
这个平台上有很多关于super
和subclassing
以及decorators
的问答。 我建议您搜索一下并阅读这些内容。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.