以与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

查看:614
本文介绍了以与Python 2.7和Python 3.5兼容的方式使用abc.ABCMeta的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想创建一个类,该类具有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.

对于那些更喜欢future而不是six的人,相关功能为

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆