【问题标题】:Python3 abstract class TypeError not raisedPython3 抽象类 TypeError 未引发
【发布时间】:2016-05-21 13:47:33
【问题描述】:

我正在运行 python 2.7、3.4 和 3.5。只有 2.7 使用以下代码引发 TypeError。我想知道我是否做错了什么,这是一个已知的错误还是其他什么?

from abc import ABCMeta, abstractmethod

class Base(object):
    __metaclass__ = ABCMeta

    @abstractmethod
    def bar(self):
        pass


class Concrete(Base):
    pass


confused = Concrete()

在 Python 2.7 中,我收到以下(有用的)错误:

Traceback (most recent call last):
  File "confused.py", line 16, in <module>
    confused = Concrete()
TypeError: Can't instantiate abstract class Concrete with abstract methods bar

但在 Python3.x 中它运行时没有错误(坏)。谢谢。

【问题讨论】:

    标签: python-2.7 python-3.x exception abstract-class


    【解决方案1】:

    python3 中声明一个抽象基类更改为:

    import abc
    
    class Base(metaclass=abc.ABCMeta):
    
        @abc.abstractmethod
        def bar(self):
            pass
    
    
    class Concrete(Base):
        pass
    
    
    Concrete() # Will raise a TypeError
    

    【讨论】:

      【解决方案2】:

      它们在 Python2.x 和 Python3.x 中的行为不同。

      Python3.6

      # importing abstract base classes module
      import abc
      
      class GetterSetter(abc.ABC):
          '''
          ABSTRACT BASE CLASSES:
      
          -  An abstract base class is a kind of 'model' for other classes to be defined.
              - It is not designed to construct instances, but can be subclassed by regular classes
      
          - Abstract classes can define interface, or methods that must be implemented by its subclasses.
      
          '''
      
      
          # Abstract classes are not designed to be instantiated, only to be subclassed
      
          #  decorator for abstract class
          @abc.abstractmethod
          def set_val(self, input):
              """set the value in the instance"""
              return
      
          @abc.abstractmethod
          def get_val(self):
              """Get and return a value from the instance..."""
              return
      
      # Inheriting from the above abstract class
      class MyClass(GetterSetter):
      
          # methods overriding in the GetterSetter
          def set_val(self, input):
              self.val = input
      
          def get_val(self):
              return self.val
      
      
      # Instantiate
      x = MyClass()
      print(x) # prints the instance <__main__.MyClass object at 0x10218ee48>
      x = GetterSetter() #throws error, abstract classes can't be instantiated
      

      Python2.x

      import abc
      
      class GetterSetter(object):
          # meta class is used to define other classes
          __metaclass__ = abc.ABCMeta
      
      
          #  decorator for abstract class
          @abc.abstractmethod
          def set_val(self, input):
              """set the value in the instance"""
              return
      
          @abc.abstractmethod
          def get_val(self):
              """Get and return a value from the instance..."""
              return
      
      # Inheriting from the above abstract class
      class MyClass(GetterSetter):
      
          # methods overriding in the GetterSetter
          def set_val(self, input):
              self.val = input
      
          def get_val(self):
              return self.val
      
      
      # Instantiate
      x = GetterSetter()
      print(x)
      x = GetterSetter() #throws error, abstract classes can't be instantiated
      

      查看我的答案here

      【讨论】:

        猜你喜欢
        • 2018-07-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-06-13
        • 1970-01-01
        • 2017-01-10
        相关资源
        最近更新 更多