Mixin类是抽象基类吗?

7
Mixin类是抽象基类吗?在下面的示例中,调用test_base将失败,因为Python无法解析例如self.assertEqual的内容。
此外,PyCharm是否有误,标记像下面这样的Mixin类具有未解决的属性错误?
class TestConverterMixin(object):
    def setUp(self):
        self.alt_hasher = getattr(hash, self.converter.__class__.__name__)

    def test_base(self):
        with self.settings(PASSWORD_HASHERS=[self.hasher, ]):
            load_hashers(settings.PASSWORD_HASHERS)

            for password in PASSWORDS:
                orig = self.alt_hasher.encrypt(password)
                conv = self.converter.from_orig(orig)

                # see if we get a working hash:
                self.assertTrue(check_password(password, conv))

                # convert back and test with passlib:
                back = self.converter.to_orig(conv)
                self.assertEqual(orig, back)
2个回答

5
Mixin类是抽象基类吗?对于你的情况来说,最准确的回答是否定的,但它可能应该是。你所指出的原因是你的类作为独立存在是无法生存的。通过将其作为ABC,你明确地告诉任何查看你的类(如pycharm)的人。
from abc import ABCMeta, abstractmethod

class TestConverterMixin(object):
    __metaclass__ = ABCMeta

    @abstractmethod
    def assertEqual(self, other):
        "Need concrete implementation somewhere"

    .... the rest of your code 

问题在于你需要对所有其他方法(self.AssertTrue、self.converter等)进行相同的操作。除非你有其他想法,否则这看起来就像是unittest.TestCase的一个子类。
哦,还有PyCharm错了吗?不,他们是对的。如果你将其作为ABC或TestCase的子类,则不会出现投诉。如果你使用接口,例如zope.Interface,pycharm和类似工具通常会出错,因为它们不理解注册和查找过程。(这是在Python核心之外的)

谢谢 - 是的,我一般在寻找单元测试,只是在某些情况下混合类(Mixin)更有效,但也许继承unittest.TestCase的子类同样好用。 - smithy

2

我一直遇到问题,无法让PyCharm不抱怨混入类中未解决的属性引用错误。特别是,我还有某些混入类依赖于其他混合类,但我无法让一个继承另一个。但是我发现了这种几乎完美的方法,可以让PyCharm 2017.1开心:

class Human:
    def is_male(self):
        return True

class BeardMixin:
    _facial_hair = {'length': 7, 'color': 'brown'}

    def has_beard(self):
        return True

class BeardLengthMixin:
    """Mixin for class Human with BeardMixin to provide get_beard_length()"""

    def get_beard_length(self):
        assert isinstance(self, (Human, BeardMixin))
        # PyCharm will now not complain about any of these 3 attributes
        if self.is_male() and self.has_beard():
            return self._facial_hair['length']

assert语句为PyCharm提供了有关self可能是哪些类型的必要信息。 但是,它也有一个缺点:assert语句本身并不执行你认为它执行的操作:它仅检查self是否属于任一类型,而不是两种类型都属于。不幸的是,使用两个assert语句是行不通的,因为对于PyCharm的类型推断来说,第二个assert语句会覆盖第一个。


那看起来是个很酷的技巧,所以我尝试在我的Mixin上使用它,确实停止了它对预期超类属性未解决引用的抱怨...但现在它开始抱怨对Mixin中未解决的类方法的引用。哦,好吧,就这样忍受一些黄色标记吧。 - aptwebapps
1
@aptwebapps: assert isinstance(self, A) and isinstance(self, AMixin) - 这对我很有帮助,但我不喜欢必须在多个地方(方法)中放置它。 - Kukosk

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接