标签: abc

为什么在Python中使用抽象基类?

因为我习惯于在Python中使用旧的鸭子打字方式,所以我无法理解对ABC(抽象基类)的需求.的帮助下是如何使用它们好.

我试图在PEP中阅读理由,但它超越了我的脑海.如果我正在寻找一个可变序列容器,我会检查__setitem__,或者更有可能尝试使用它(EAFP).我没有遇到数字模块的实际用途,它确实使用了ABC,但这是我必须理解的最接近的数字模块.

有人能解释一下我的理由吗?

python abstract-class abc

192
推荐指数
5
解决办法
6万
查看次数

以某种方式使用abc.ABCMeta,它与Python 2.7和Python 3.5兼容

我想创建一个具有abc.ABCMeta元类的类,并且与Python 2.7和Python 3.5兼容.到目前为止,我只能在2.7或3.5上成功实现这一点 - 但从不同时在两个版本上.有人可以帮我一把吗?

Python 2.7:

import abc
class SomeAbstractClass(object):
    __metaclass__ = abc.ABCMeta
    @abc.abstractmethod
    def do_something(self):
        pass
Run Code Online (Sandbox Code Playgroud)

Python 3.5:

import abc
class SomeAbstractClass(metaclass=abc.ABCMeta):
    @abc.abstractmethod
    def do_something(self):
        pass
Run Code Online (Sandbox Code Playgroud)

测试

如果我们使用合适版本的Python解释器(Python 2.7 - >示例1,Python 3.5 - >示例2)运行以下测试,则它在以下两种情况下都会成功:

import unittest
class SomeAbstractClassTestCase(unittest.TestCase):
    def test_do_something_raises_exception(self):
        with self.assertRaises(TypeError) as error:
            processor = SomeAbstractClass()
        msg = str(error.exception)
        expected_msg = "Can't instantiate abstract class SomeAbstractClass with abstract methods do_something"
        self.assertEqual(msg, expected_msg)
Run Code Online (Sandbox Code Playgroud)

问题

在使用Python 3.5运行测试时,预期的行为不会发生(TypeError在实例化时不会引发SomeAbstractClass):

======================================================================
FAIL: test_do_something_raises_exception (__main__.SomeAbstractClassTestCase)
----------------------------------------------------------------------
Traceback …
Run Code Online (Sandbox Code Playgroud)

python metaclass abc python-2.7 python-3.5

45
推荐指数
4
解决办法
2万
查看次数

Python - 测试抽象基类

我正在寻找在抽象基类中定义的测试方法的方法/最佳实践.我可以直接想到的一件事是在基类的所有具体子类上执行测试,但这在某些时候似乎过多.

考虑这个例子:

import abc

class Abstract(object):

    __metaclass__ = abc.ABCMeta

    @abc.abstractproperty
    def id(self):
        return   

    @abc.abstractmethod
    def foo(self):
        print "foo"

    def bar(self):
        print "bar"
Run Code Online (Sandbox Code Playgroud)

是否可以在bar不进行任何子类化的情况下进行测试?

python oop testing abc

32
推荐指数
6
解决办法
1万
查看次数

python @abstractmethod装饰

我读过有关抽象基类的python文档:

这里:

abc.abstractmethod(function) 指示抽象方法的装饰员.

使用这个装饰器需要该类的元类是ABCMeta从它派生的.ABCMeta 除非所有抽象方法和属性都被覆盖,否则无法实例化具有派生自元类的类.

在这里

您可以将@abstractmethod装饰器应用于必须实现的draw()等方法; 然后,Python将为未定义该方法的类引发异常.请注意,只有在您实际尝试创建缺少该方法的子类的实例时才会引发该异常.

我已经用这段代码测试了一下:

import abc

class AbstractClass(object):
  __metaclass__ = abc.ABCMeta

  @abc.abstractmethod
  def abstractMethod(self):
    return

class ConcreteClass(AbstractClass):
  def __init__(self):
    self.me = "me"

c = ConcreteClass()
c.abstractMethod()
Run Code Online (Sandbox Code Playgroud)

代码很好,所以我不明白.如果我输入c.abstractMethod我得到:

<bound method ConcreteClass.abstractMethod of <__main__.ConcreteClass object at 0x7f694da1c3d0>>
Run Code Online (Sandbox Code Playgroud)

我在这里缺少什么?ConcreteClass 必须实现抽象方法,但我也不例外.

python abc abstract-methods

31
推荐指数
2
解决办法
3万
查看次数

确定Python类是抽象基类还是混凝土

我的Python应用程序包含许多抽象类和实现.例如:

import abc
import datetime

class MessageDisplay(object):
    __metaclass__ = abc.ABCMeta

    @abc.abstractproperty
    def display(self, message):
        pass

class FriendlyMessageDisplay(MessageDisplay):
    def greet(self):
        hour = datetime.datetime.now().timetuple().tm_hour

        if hour < 7:
            raise Exception("Cannot greet while asleep.")
        elif hour < 12:
            self.display("Good morning!")
        elif hour < 18:
            self.display("Good afternoon!")
        elif hour < 20:
            self.display("Good evening!")
        else:
            self.display("Good night.")

class FriendlyMessagePrinter(FriendlyMessageDisplay):
    def display(self, message):
        print(message)
Run Code Online (Sandbox Code Playgroud)

FriendlyMessagePrinter 是一个我们可以使用的具体类......

FriendlyMessagePrinter().greet()
Run Code Online (Sandbox Code Playgroud)
Good night.
Run Code Online (Sandbox Code Playgroud)

...但是MessageDisplay并且FriendlyMessageDisplay是抽象类并且尝试实例化一个会导致错误:

TypeError: Can't instantiate abstract class MessageDisplay with abstract methods say
Run Code Online (Sandbox Code Playgroud)

如何检查给定的类对象是否是(不可实例化的)抽象类?

python abstract-class abc

28
推荐指数
2
解决办法
7037
查看次数

如何检查numpy dtype是否是完整的?

如何检查numpy dtype是否是完整的?我试过了:

issubclass(np.int64, numbers.Integral)
Run Code Online (Sandbox Code Playgroud)

但它给了False.


更新:它现在给出True.

python integer numpy abc

28
推荐指数
4
解决办法
1万
查看次数

无法使用抽象方法实例化抽象类

我正在研究一种lib,由于一个奇怪的原因,我有这个错误.

  • 是我的代码.当然@ abc.abstractmethod必须取消注释
  • 是我的测试

抱歉,无法复制并粘贴它

我的基础是下面的代码有效

test.py

import abc
import six

@six.add_metaclass(abc.ABCMeta)
class Base(object):

    @abc.abstractmethod
    def whatever(self,):
        raise NotImplementedError

class SubClass(Base):

    def __init__(self,):

        super(Base, self).__init__()
        self.whatever()

    def whatever(self,):
        print("whatever")
Run Code Online (Sandbox Code Playgroud)

在python shell中

>>> from test import *
>>> s = SubClass()
whatever
Run Code Online (Sandbox Code Playgroud)

为什么我的名册模块我有这个错误

Can't instantiate abstract class Player with abstract methods _Base__json_builder, _Base__xml_builder
Run Code Online (Sandbox Code Playgroud)

提前致谢

python abstract-class abc six

25
推荐指数
1
解决办法
3万
查看次数

Python 泛型缺少交集类型的解决方法?

我遇到了一个可以通过交叉类型轻松解决的问题(目前正在讨论但尚未实施),并且想知道最干净的解决方法是什么。

当前设置和问题

我当前的设置大致对应于以下动物的 ABC 层次结构。有许多动物“特征”(CanFlyCanSwim等)被定义为抽象子类(尽管它们也可以被定义为 mixin)。

from abc import ABC, abstractmethod

class Animal(ABC):
    @abstractmethod
    def name(self) -> str: ...  
    
class CanFly(Animal):
    @abstractmethod
    def fly(self) -> None: ...
    
class CanSwim(Animal):
    @abstractmethod
    def swim(self) -> None: ...
Run Code Online (Sandbox Code Playgroud)

以此我定义了特定的动物类别,包括抽象的和具体的:

class Bird(CanFly):
    def fly(self) -> None:
        print("flap wings")
    
class Penguin(Bird, CanSwim):
    def name(self) -> str:
        return "penguin"
    def swim(self) -> None:
        print("paddle flippers")
Run Code Online (Sandbox Code Playgroud)

我还定义了一个通用类来抚摸特定类型的动物:

from typing import Generic, TypeVar

T = TypeVar("T", bound=Animal, contravariant=True)

class Petter(Generic[T], ABC):

    @abstractmethod …
Run Code Online (Sandbox Code Playgroud)

python abc python-3.x mypy python-typing

24
推荐指数
1
解决办法
4054
查看次数

从coverage报告中排除abstractproperties

我有一个抽象的基类:

class MyAbstractClass(object):
    __metaclass__ = ABCMeta

    @abstractproperty
    def myproperty(self): pass
Run Code Online (Sandbox Code Playgroud)

但是当我在我的项目中运行nosetests(覆盖率)时,它会抱怨属性def line未经测试.它实际上无法测试(AFAIK),因为抽象类的实例化将导致异常被引发.

有没有解决方法,或者我只需要接受<100%的测试覆盖率?

当然,我可以删除ABCMeta用法并简单地提升基类NotImpementedError,但我更喜欢前一种方法.

python code-coverage abc nosetests coverage.py

23
推荐指数
3
解决办法
4577
查看次数

装饰器上的抽象方法

在python中,有没有办法让抽象方法上的装饰器继续执行派生的实现?

例如,在

import abc

class Foo(object):
    __metaclass__ = abc.ABCMeta

    @abc.abstractmethod
    @some_decorator
    def my_method(self, x):
        pass

class SubFoo(Foo):
    def my_method(self, x):
        print x
Run Code Online (Sandbox Code Playgroud)

SubFoomy_method将不会饰some_decorator据我可以告诉.有没有什么方法可以实现这一点,而无需单独装饰每个派生类Foo

python decorator abc

20
推荐指数
2
解决办法
2363
查看次数