我想创建一个具有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) 我正在寻找在抽象基类中定义的测试方法的方法/最佳实践.我可以直接想到的一件事是在基类的所有具体子类上执行测试,但这在某些时候似乎过多.
考虑这个例子:
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文档:
从这里:
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应用程序包含许多抽象类和实现.例如:
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)
如何检查给定的类对象是否是(不可实例化的)抽象类?
如何检查numpy dtype是否是完整的?我试过了:
issubclass(np.int64, numbers.Integral)
Run Code Online (Sandbox Code Playgroud)
但它给了False.
更新:它现在给出True.
我正在研究一种lib,由于一个奇怪的原因,我有这个错误.
抱歉,无法复制并粘贴它
我的基础是下面的代码有效
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)
提前致谢
我遇到了一个可以通过交叉类型轻松解决的问题(目前正在讨论但尚未实施),并且想知道最干净的解决方法是什么。
我当前的设置大致对应于以下动物的 ABC 层次结构。有许多动物“特征”(CanFly、CanSwim等)被定义为抽象子类(尽管它们也可以被定义为 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) 我有一个抽象的基类:
class MyAbstractClass(object):
__metaclass__ = ABCMeta
@abstractproperty
def myproperty(self): pass
Run Code Online (Sandbox Code Playgroud)
但是当我在我的项目中运行nosetests(覆盖率)时,它会抱怨属性def line未经测试.它实际上无法测试(AFAIK),因为抽象类的实例化将导致异常被引发.
有没有解决方法,或者我只需要接受<100%的测试覆盖率?
当然,我可以删除ABCMeta用法并简单地提升基类NotImpementedError,但我更喜欢前一种方法.
在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)
SubFoo的my_method将不会饰some_decorator据我可以告诉.有没有什么方法可以实现这一点,而无需单独装饰每个派生类Foo?
abc ×10
python ×10
coverage.py ×1
decorator ×1
integer ×1
metaclass ×1
mypy ×1
nosetests ×1
numpy ×1
oop ×1
python-2.7 ×1
python-3.5 ×1
python-3.x ×1
six ×1
testing ×1