具有多重继承和元类定义的语法错误

SyntaxError with multi-inheritance and metaclass definition

我运行遇到了一个非常奇怪的错误。我的项目涉及以下代码段:

from contextlib import contextmanager
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker, scoped_session


class Singleton(type):
    _instances = {}

    def __call__(cls, *args, **kwargs):
        if cls not in cls._instances:
            cls._instances[cls] = super(Singleton, cls).__call__(*args, **kwargs)
        return cls._instances[cls]

    def get_instance(cls):
        return cls._instances[cls]


class SessionManager(object, metaclass=Singleton):

    _engines = {}
    _db_config = {}

    def __init__(self, db_config: dict, **kwargs):
        """
        Parent initializer.  Takes SQLAlchemy database config parameters.
        :param db_config: Database config, consisting of known SQLAlchemy
        config key/values
        :type db_config: dict
        :return: self
        """
        self._engine = None
        self._engine_string = None
        self._db_config = db_config
   
      ...
      ...

当我在 macOS 中 运行 使用 Python 3.5 时,它可以正常工作。但是,当我将项目迁移到 Ubuntu 18.04 和 运行 以及 Python 3.6 时,它会抱怨语法错误:

Traceback (most recent call last):
  File "run.py", line 5, in <module>
    from views import default
  File "/home/john/p/a/views/default.py", line 11, in <module>
    from utils.TaskManagerQueue import TaskManagerQueue
  File "/home/john/p/a/utils/TaskManagerQueue.py", line 5, in <module>
    from utils.SessionManager import SessionManager
  File "/home/john/p/a/utils/SessionManager.py", line 19
    class SessionManager(object, metaclass=Singleton):
                                          ^
SyntaxError: invalid syntax

网上查了一下,确认class多重继承class SessionManager(object, metaclass=Singleton)是正确的。这里可能有什么问题?

我很确定您确实在 Ubuntu 机器上使用 Python 2。在 Python 2 下,使用 a __metaclass__ attribute. Keyword-style metaclasses were added in Python 3.0.

设置元类

根据您安装 Python 的方式,您可能需要使用 python3 甚至 python3.6 而不是 python 来调用您的代码。请注意 default python in Ubuntu 18.04 is still version 2.7.

我建议你设置一个正确版本的 virtualenv 来简化这个,例如通过 the venv module or something like Pipenv.