我想创建一个类 abc.ABCMeta
作为元类并且与 Python 2.7 和 Python 3.5 兼容。直到现在,我只在 2.7 或 3.5 上成功地做到了这一点——但从来没有同时在两个版本上做到过。有人可以帮我吗?
蟒蛇2.7:
import abc
class SomeAbstractClass(object):
__metaclass__ = abc.ABCMeta
@abc.abstractmethod
def do_something(self):
pass
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),它在两种情况下都会成功:
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 运行测试时,预期的行为不会发生( TypeError
在实例化时不会引发 SomeAbstractClass
):
======================================================================
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
:
Python 2.7 incompatible
Raises exception:
File "/home/tati/sample_abc.py", line 24
class SomeAbstractClass(metaclass=abc.ABCMeta):
^
SyntaxError: invalid syntax
原文由 Tatiana Al-Chueyr 发布,翻译遵循 CC BY-SA 4.0 许可协议
您可以使用
six.add_metaclass
或six.with_metaclass
:six
是一个 Python 2 和 3 兼容库。您可以通过运行pip install six
或通过将最新版本的six.py
下载到您的项目目录来安装它。对于那些更喜欢
future
而不是six
的人,相关功能是future.utils.with_metaclass
。