【问题标题】:How to dynamically assign class methods from within class?如何从类内动态分配类方法?
【发布时间】:2020-06-21 13:57:37
【问题描述】:
import util
class C():
    save = util.save
setattr(C, 'load', util.load)

C.save 对 linter 可见 - 但 C.load 不可见。因此,从类本身和从外部分配类方法之间存在一些差异。文档构建者的交易相同;例如Sphinx 不会承认:meth:C.load - 相反,需要做:func:util.load,如果loadC 的方法,这是误导。 IDE (Spyder) 也无法通过self.load 代码“转到”方法。

最终目标是让 linter (+docs & IDE) 将 load 识别为 C 的方法,就像 C.save 一样,但类方法分配需要是动态的 (context)。这可以实现吗?


注意:动态分配的目的是自动从模块中提取方法(例如util),而不是在添加/删除方法时手动更新C

【问题讨论】:

    标签: python python-3.x python-sphinx static-analysis


    【解决方案1】:

    免责声明:此解决方案并非适用于所有用例,请参阅 cmets。我把它留在这里,因为它在某些情况下可能仍然有用。

    我不知道 linter 和 Sphinx,但是如果你使用类型提示预先声明它,像 PyCharm 这样的 IDE 将识别该方法。在下面的代码中,如果没有 load: Callable[[], None] 行,我会收到警告“未解析的属性引用”,但在该行中,文件中没有警告。查看docs 了解有关类型提示的更多信息。

    注意事项:

    • 即使使用更通用的load: Callable,类型检查器也很满意。
    • 如果您不总是声明可调用对象,则有效声明为 load: Optional[Callable] = None。这意味着默认值为无。如果你在没有设置的情况下调用它,你会得到一个错误,但无论如何你已经得到了,这与这个类型无关。

    附言我没有你的utils,所以我在文件本身中定义了一些函数。

    from typing import Callable
    
    
    def save():
        pass
    
    
    def load():
        pass
    
    
    class C:
        load: Callable[[], None]
        save = save
    
    
    setattr(C, 'load', load)
    
    C.load()
    

    【讨论】:

    • load: ...仍在C之内,这违背了动态赋值的目的;这个想法是自动从模块中提取方法,而不是在添加/删除方法时手动更新C
    • 啊,我现在看到了你的用例。确实,那么这个解决方案就行不通了,每次动态添加方法时,您仍然需要向 C 类添加一些内容。
    猜你喜欢
    • 2013-01-13
    • 1970-01-01
    • 2016-05-05
    • 1970-01-01
    • 2016-01-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-03
    相关资源
    最近更新 更多