我在github上写了一个软件.它基本上是一个带有一些额外功能的托盘图标.我想提供一段工作代码而不必让用户安装本质上依赖于可选功能的东西,我实际上并不想导入我不会使用的东西所以我认为这样的代码将是"好的解决方案":
---- IN LOADING FUNCTION ----
features = []
for path in sys.path:
if os.path.exists(os.path.join(path, 'pynotify')):
features.append('pynotify')
if os.path.exists(os.path.join(path, 'gnomekeyring.so')):
features.append('gnome-keyring')
#user dialog to ask for stuff
#notifications available, do you want them enabled?
dlg = ConfigDialog(features)
if not dlg.get_notifications():
features.remove('pynotify')
service_start(features ...)
---- SOMEWHERE ELSE ------
def service_start(features, other_config):
if 'pynotify' in features:
import pynotify
#use pynotify...
Run Code Online (Sandbox Code Playgroud)
但是有一些问题.如果用户格式化他的机器并安装最新版本的操作系统并重新部署此应用程序,则功能会在没有警告的情况下突然消失.解决方案是在配置窗口中显示:
if 'pynotify' in features:
#gtk checkbox
else:
#gtk label reading "Get pynotify and enjoy notification pop ups!"
Run Code Online (Sandbox Code Playgroud)
但是,如果这是一个mac,我怎么知道我不是在寻找一个他们永远无法填充的依赖关系的疯狂追逐用户?
第二个问题是:
if os.path.exists(os.path.join(path, …Run Code Online (Sandbox Code Playgroud) 我正在研究实现科学模型的python软件包,我想知道什么是处理可选功能的最佳方法。这是我想要的行为:如果无法导入一些可选的依赖项(例如,在无头计算机上绘制模块),我想在我的类中禁用使用这些模块的功能,并警告用户如果他尝试使用它们以及所有这些,而不会破坏执行力。因此以下脚本在任何情况下均适用:
mymodel.dostuff()
mymodel.plot() <= only plots if possible, else display log an error
mymodel.domorestuff() <= get executed regardless of the result of the previous statement
Run Code Online (Sandbox Code Playgroud)
到目前为止,我看到的选项如下:
__init __.py可用模块并保留它们的列表(但是如何在包装的其余部分中正确使用它?)try import ...
except ...语句这些选项应该可以使用,但是它们似乎都非常笨拙且难以维护。如果我们想完全删除依赖项怎么办?还是强制性?