Python 一般来说,如果用户缺少包,我应该编写多个版本的代码体吗?

Python 一般来说,如果用户缺少包,我应该编写多个版本的代码体吗?,python,error-handling,runtime-error,Python,Error Handling,Runtime Error,假设我正在构建一个Python程序,在最开始的时候,我导入了两个模块-something,默认情况下它包含在Python库中,而somethingElse,它不包含在Python库中 我有两个几乎相同的函数,一个在没有somethingElse的情况下工作,另一个版本使用它工作得更好。虽然理想情况下,人们只需安装所需的依赖项,但我更希望机器/系统与somethingElse包不兼容的用户能够访问这些依赖项。 例如: 这是一种良好的做法,还是有更好的方法来解决这个问题 谢谢 一般来说,最好有一个处

假设我正在构建一个Python程序,在最开始的时候,我导入了两个模块-something,默认情况下它包含在Python库中,而somethingElse,它不包含在Python库中

我有两个几乎相同的函数,一个在没有somethingElse的情况下工作,另一个版本使用它工作得更好。虽然理想情况下,人们只需安装所需的依赖项,但我更希望机器/系统与somethingElse包不兼容的用户能够访问这些依赖项。 例如:

这是一种良好的做法,还是有更好的方法来解决这个问题


谢谢

一般来说,最好有一个处理依赖关系的pip
requirements.txt
文件或
setup.py
。但是,如果出于任何原因需要这样做,我认为最好使用一个类作为任一库的包装器,而使用者不关心导入了哪个库。例如,在您的模块中,您会有如下内容:

try:
    import better_lib

    class LibAPI(object):
        root_lib = better_lib
        def fizzle(self, *args, **kwargs):
            return self.root_lib.better_fizzle(*args, **kwargs)
        def mundun(self, n, x, **kwargs):
            floof = (n, x)
            return self.root_lib.better_mundun(floof, **kwargs)

except ImportError:
    import worse_lib

    class LibAPI(object):
        root_lib = worse_lib
        def fizzle(self, x, y, z, **kwargs):
            fizz = self.root_lib.worse_fizz(x, y)
            return self.root_lib.izzle(fizz, z, **kwargs)
        def mundun(self, *args, **kwargs):
            return self.root_lib.worse_mundun(*args, **kwargs)

lib_api = LibAPI()

通过这种方式,即使核心库可能非常不同,但在代码中,您可以以相同的方式与它们进行交互(
lib_-api.fizzle()
lib_-api.mundun()
),因为您已经将任何差异包装在一个统一的包装器中。最好将所有这些都放在一个地方,而不是在代码中杂乱无章的各处检查导入了哪个库。如果您确实需要,您仍然可以通过检查
lib\u api.root\u lib
是什么来反思使用了哪个库。

Nice!我本来打算建议猴子修补,但这是更好的办法。
try:
    import better_lib

    class LibAPI(object):
        root_lib = better_lib
        def fizzle(self, *args, **kwargs):
            return self.root_lib.better_fizzle(*args, **kwargs)
        def mundun(self, n, x, **kwargs):
            floof = (n, x)
            return self.root_lib.better_mundun(floof, **kwargs)

except ImportError:
    import worse_lib

    class LibAPI(object):
        root_lib = worse_lib
        def fizzle(self, x, y, z, **kwargs):
            fizz = self.root_lib.worse_fizz(x, y)
            return self.root_lib.izzle(fizz, z, **kwargs)
        def mundun(self, *args, **kwargs):
            return self.root_lib.worse_mundun(*args, **kwargs)

lib_api = LibAPI()