Equivalent of NotImplementedError for fields in Python

前端 未结 8 1308
北海茫月
北海茫月 2020-12-07 18:56

In Python 2.x when you want to mark a method as abstract, you can define it like so:

class Base:
    def foo(self):
        raise NotImplementedError(\"Subcl         


        
相关标签:
8条回答
  • 2020-12-07 19:50

    It seem that this question was open to both instance attributes and class attributes, I'll focus on the first topic only.

    So, for instance attributes, an alternate answer to Evan's is to define a mandatory field using pyfields:

    from pyfields import field
    
    class Base(object):
        example = field(doc="This should contain an example.")
    
    b = Base()
    b.example
    

    yields

    pyfields.core.MandatoryFieldInitError: 
       Mandatory field 'example' has not been initialized yet 
       on instance <__main__.Base object at 0x000002C1000C0C18>.
    

    Granted, it does not provide you with the ability to edit the error message by talking about subclasses. But in a way it is more realistic to not talk about subclasses - indeed in python, attributes can be overridden on instances of the base class - not only in subclasses.

    Note: I'm the author of pyfields. See documentation for details.

    0 讨论(0)
  • 2020-12-07 19:54

    A better way to do this is using Abstract Base Classes:

    import abc
    
    class Foo(abc.ABC):
    
        @property
        @abc.abstractmethod
        def demo_attribute(self):
            raise NotImplementedError
    
        @abc.abstractmethod
        def demo_method(self):
            raise NotImplementedError
    
    class BadBar(Foo):
        pass
    
    class GoodBar(Foo):
    
        demo_attribute = 'yes'
    
        def demo_method(self):
            return self.demo_attribute
    
    bad_bar = BadBar()
    # TypeError: Can't instantiate abstract class BadBar \
    # with abstract methods demo_attribute, demo_method
    
    good_bar = GoodBar()
    # OK
    

    Note that you should still have raise NotImplementedError instead of something like pass, because there is nothing preventing the inheriting class from calling super().demo_method(), and if the abstract demo_method is just pass, this will fail silently.

    0 讨论(0)
提交回复
热议问题