Python Mixin - неразрешенная ссылка на атрибут [PyCharm] - PullRequest
2 голосов
/ 17 марта 2019

Я использую миксин для разделения функциональности на другой класс. Предполагается, что этот миксин можно смешивать только с единственным дочерним классом:

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

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

в моем методе Mixin.complex_operation PyCharm выдает предупреждение 'Unresolved Attribute Reference foo'.

Правильно ли я использую миксин? Есть ли лучший способ? (Я хотел бы иметь подсказки типов и автозаполнение в моих миксинах, и я хотел бы иметь несколько миксинов.)

Ответы [ 3 ]

1 голос
/ 22 марта 2019

Объявите необходимые поля в Mixin как:

class Mixin:
    foo:str

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

Таким образом, миксин фактически объявляет поля, которые класс должен иметь для использования этого миксина. Подсказка типа создаст предупреждения, если расширяющий класс поместит несовместимый тип в объявленное поле.

edit: Заменено foo = Нет с foo: str, как предложено @ valex

1 голос
/ 17 июля 2019

Я вижу несколько вариантов.

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()
0 голосов
/ 17 марта 2019

Итак, просто для того, чтобы собрать мои мысли из комментариев для всех остальных: проблема заключается в том, чтобы два класса были неразрывно связаны при разделении функциональности.Вот мои решения:

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) Сделать класс для приема другого класса в качестве параметра

In Mixin 's __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())
...