【问题标题】:Python Mixin - Unresolved Attribute Reference [PyCharm]Python Mixin - 未解析的属性参考 [PyCharm]
【发布时间】:2019-08-08 03:23:58
【问题描述】:

我正在使用 mixin 将一系列功能分离到不同的类。这个 Mixin 只能与唯一的子类混合:

class Mixin:
    def complex_operation(self):
        return self.foo.capitalize()

class A(Mixin):
    def __init__(self):
        self.foo = 'foo'

在我的方法Mixin.complex_operation PyCharm 中给出警告“未解决的属性参考 foo”。

我是否正确使用了 mixin 模式? 有更好的方法吗?(我想在我的 mixin 中添加类型提示和自动补全功能,并且我想拥有多个 mixins。)

【问题讨论】:

  • 我复制并粘贴了您的代码,print (A().complex_operation()) 打印了“Foo”。我们应该看到更多代码吗?至于更好的方法,继承对于 mixins 来说很好,类型提示 + 自动补全完全取决于您选择的 IDE。
  • 是的,它可以工作 - 但正如提到的 IDE 抱怨,我没有自动完成......
  • 您使用的是哪个 IDE?它不应该评估函数中的变量,因为即使 Python 也不这样做——正是出于这个原因。
  • 我正在使用 PyCharm。它确实会检查我是否使用了现有变量,但它当然可以让我执行代码,即使它怀疑它有问题。
  • 我对 PyCharm 了解不多,但似乎它希望 self 拥有 foo,但 Mixins 没有。它有一点——不是每个使用这个 mixin 的类都保证有一个foo。也许您希望foo 成为Mixin 的类属性(或至少在__init__ 中设置)而不是A。

标签: python pycharm mixins


【解决方案1】:

在 Mixin 中声明必要的字段,例如:

class Mixin:
    foo: str

    def complex_operation(self):
        return self.foo.capitalize() 

通过这种方式,mixin 实际上声明了一个类必须能够使用这个 mixin 的字段。如果扩展类将不兼容的类型放入声明的字段中,类型提示将创建警告。

编辑:按照@valex 的建议,将 foo = None 替换为 foo:str

【讨论】:

    【解决方案2】:

    我看到的选项很少。

    1) 类型注释(我认为这是最干净的解决方案):

    class Mixin:
        foo: str
    
        def complex_operation(self):
            return self.foo.capitalize()
    

    2) 默认None(@ikamen 选项):

    class Mixin:
        foo = None
    
        def complex_operation(self):
            return self.foo.capitalize()
    

    3) 抑制类或特定行的未解决引用错误(我认为这比前两个更脏):

    # noinspection PyUnresolvedReferences
    class Mixin:
        def complex_operation(self):
            return self.foo.capitalize()
    
    class Mixin:
        def complex_operation(self):
            # noinspection PyUnresolvedReferences
            return self.foo.capitalize()
    

    【讨论】:

    • 我认为类型注解绝对比None好。我也把它放在了我的答案中。
    • 类型注释版本是否设置了一个类变量foo,其值为"",还是只是一个公告?如果您希望有一种方法,这将如何工作?
    • @Minix 类型注解只是一个公告。
    【解决方案3】:

    所以只是为了为其他人编译我从 cmets 中的想法: 问题是在分离功能的同时保持两个类的内在联系。这是我的解决方案:

    1) 制作模块

    有另一个文件,比如mixin.py,它具有complex_operation 作为函数。与其接受self 作为参数,不如让它接受一个字符串:

    # mixin.py
    
    def complex_operation (foo: str) -> str: return foo.capitalize()
    
    # main.py
    
    from ai import complex_operation
    class A: 
        def __init__(self): self.foo = "foo"
    print (complex_operation (A().foo))
    

    2) 使一个类接受另一个类作为参数

    在Mixin 的__init__ 函数中,添加一个参数来接受A,然后在其方法中使用它:

    # mixin.py
    
    class Mixin: 
        def __init__(self, a: A): self.a = a
        def complex_operation(self): return self.a.foo.capitalize()
    
    # main.py
    
    from mixin import Mixin
    class A:
        def __init__(self): self.foo = "foo"
    
    print (Mixin (A()).complex_operation())
    

    【讨论】:

    • 我喜欢某些情况下的模块解决方案。人们应该牢记这种可能性。
    猜你喜欢
    • 2019-01-14
    • 1970-01-01
    • 2014-05-05
    • 1970-01-01
    • 1970-01-01
    • 2015-11-12
    • 1970-01-01
    • 2020-03-05
    • 2019-01-10
    相关资源
    最近更新 更多