在python中控制导入可选/额外库

2024-10-01 09:20:22 发布

您现在位置:Python中文网/ 问答频道 /正文

Setuptools允许您定义额外的依赖项。如何选择导入这些文件

作为一个例子,考虑一个DB包装器,它可以为无数数据库

提供一些功能。

setup.py

extras_require={
    'postgres': ['postgresLibrary'],
    'mysql': ['mysqlLibrary'],
    ...
},

类定义

import postgresLibrary  <--- these imports will fail if extras not installed
import mysqlLibrary     


class DB:
    def __init__(self, db_type):
        if db_type == 'postgres':
            self.conn = PostgresConnection()
        elif db_type == 'mysql':
            self.conn == MySQLConnection()
        ...

py可能允许最终用户有选择地安装他们选择的db库,但我不清楚有选择地导入库的最佳方式是什么。我不太愿意在函数或构造函数中导入它们,但除了要求最终用户安装他们可能不想要/不需要的所有库之外,我想不出任何其他方法来实现这一点


Tags: pyimportselfextrasdbif定义type
2条回答

这有点像黑客,但一个选择是将导入包装在try/except块中。如果postgres库不可用,并且用户尝试使用db_类型的postgres初始化db对象,那么您可能会针对缺少的导入引发异常

我最初的回答不起作用,但我把它留在这里,这样评论才有意义

一种方法是为每种类型的数据库创建一个类。主DB类不需要可选的导入,postgres DB类需要postgres库,但不需要mysql库

class DB:
    def __init__(self, db_type):
        if db_type == 'postgres':
            self.db = PostgresDB()
        elif db_type == 'mysql':
            self.db == MySQLDB()
        ...
   def get_connection(self):
        return self.db.conn

import postgresLibrary
class PostgresDB:
    def __init__(self):
    self.conn = PostgresConnection

这是python中为数不多的几种情况之一,我认为单例设计模式可能很有用,可以作为一种有选择地将全局变量保存在内存中的机制。例如,代替

import postgresLibrary
import mysqlLibrary

您可以创建一个类来跟踪当前导入的模块,并且只有尝试在第一次使用它们时导入它们。例如,文件singleton.py

class SingletonBase:
    def __init__(self):
        self._modules = {}
    def __getattr__(self, module_name):
        if not module_name in self._modules:
            self._modules[module_name] = __import__(module_name)
        return self._modules[module_name]

Singleton = SingletonBase()

然后,您可以在本地使用postgresLibrary,方法是按照

from singleton import Singleton as S
...
postgresLibrary = S.postgresLibrary.PostgresConnection()

相关问题 更多 >