以与Python 2.7和Python 3.5兼容的方式使用abc.ABCMeta [英] Using abc.ABCMeta in a way it is compatible both with Python 2.7 and Python 3.5
问题描述
我想创建一个类,该类具有abc.ABCMeta
作为元类,并且与Python 2.7和Python 3.5兼容.到目前为止,我仅在2.7或3.5上成功完成了此操作-但从未同时在两个版本上成功完成此操作.有人可以帮我吗?
I'd like to create a class which has abc.ABCMeta
as a metaclass and is compatible both with Python 2.7 and Python 3.5. Until now, I only succeeded doing this either on 2.7 or on 3.5 - but never on both versions simultaneously. Could someone give me a hand?
Python 2.7:
Python 2.7:
import abc
class SomeAbstractClass(object):
__metaclass__ = abc.ABCMeta
@abc.abstractmethod
def do_something(self):
pass
Python 3.5:
Python 3.5:
import abc
class SomeAbstractClass(metaclass=abc.ABCMeta):
@abc.abstractmethod
def do_something(self):
pass
测试
如果我们使用合适版本的Python解释器(Python 2.7->示例1,Python 3.5->示例2)运行以下测试,则在两种情况下均成功:
Testing
If we run the following test using the suitable version of the Python interpreter (Python 2.7 -> Example 1, Python 3.5 -> Example 2), it succeeds in both scenarios:
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)
问题
使用Python 3.5运行测试时,未发生预期的行为(实例化SomeAbstractClass
时未引发TypeError
):
======================================================================
FAIL: test_do_something_raises_exception (__main__.SomeAbstractClassTestCase)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/home/tati/sample_abc.py", line 22, in test_do_something_raises_exception
processor = SomeAbstractClass()
AssertionError: TypeError not raised
----------------------------------------------------------------------
使用Python 2.7运行测试会引发SyntaxError
:
Whereas running the test using Python 2.7 raises a SyntaxError
:
Python 2.7 incompatible
Raises exception:
File "/home/tati/sample_abc.py", line 24
class SomeAbstractClass(metaclass=abc.ABCMeta):
^
SyntaxError: invalid syntax
推荐答案
您可以使用 six.add_metaclass
或 six.with_metaclass
:
You could use six.add_metaclass
or six.with_metaclass
:
import abc, six
@six.add_metaclass(abc.ABCMeta)
class SomeAbstractClass():
@abc.abstractmethod
def do_something(self):
pass
six
是 Python 2和3兼容性库 .您可以通过运行pip install six
或将最新版本的six.py
下载到项目目录中来安装它.
six
is a Python 2 and 3 compatibility library. You can install it by running pip install six
or by downloading the latest version of six.py
to your project directory.
For those of you who prefer future
over six
, the relevant function is future.utils.with_metaclass
.
这篇关于以与Python 2.7和Python 3.5兼容的方式使用abc.ABCMeta的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!