代码之家  ›  专栏  ›  技术社区  ›  McKay

相互调用的元类方法的最佳实践是什么?

  •  3
  • McKay  · 技术社区  · 7 年前

    我正在尝试构建一个元类,我只是想我真的得到了它。我想为这个元类的每个实例提供类方法。

    class MyMeta(type):
        """A metaclass"""
        def __new__(mcs, name, bases, attributes):
            pass
    
        def _foo(cls):
            pass
    
        def _bar(cls):
            cls._foo()
    

    当我在上面运行pylint时 cls._foo 有困难:

    [pylint] E1120:No value for argument 'cls' in unbound method call
    

    当我试着运行代码时(我的代码比这更复杂),它似乎运行得很好,并且做了我期望它做的事情。那么我该怎么解决这个案子呢?它的确切含义是什么。

    这听起来像是其他与未正确声明为 @staticmethods ,但我不能将其标记为 @classmethod 因为这将是一个元类方法。

    相关的搜索似乎在谈论人们动态添加构造函数或其他东西的地方,我认为情况并非如此。我对元类还有什么误解吗?

    我真正想要的是在元类中定义的互相调用的类方法。有更好的方法吗?

    1 回复  |  直到 7 年前
        1
  •  2
  •   jsbueno    7 年前

    [pylint]E1120:未绑定方法调用中的参数“cls”没有值

    _foo _bar 方法只是普通的Python方法——这意味着在调用这些方法时,Python将自动填充对每个类(元类实例)的引用。

    而且,由于这是一个元类,为了清晰、语义和可读性,最好像您所做的那样:将其第一个参数命名为 cls 而不是 self .

    问题是pylint没有了解这一点:它很可能期望一个硬编码的 自己 . 你的代码,在这方面是不可触及的。

    你所要做的就是添加一个元注释,让pylint忽略这些行——幸运的是,pylint允许它在块级别,而有些工具需要在每一行中标记它。

    class MyMeta(type):
        """A metaclass"""
        # pylint: disable=no-value-for-parameter
    
        def __new__(mcs, name, bases, attributes):
            pass
    
        def _foo(cls):
            pass
    
        def _bar(cls):
            cls._foo()
    

    您的示例元类,带有“元注释”,以便pylint忽略您的非错误。