Python 参数化导入语句

Python 参数化导入语句,python,Python,我维护一个Python模块,该模块包装并公开DLL的功能(也由我维护)。与DLL的接口使用ctypes 多亏了ctypes的奇迹,这一切都非常有效。然而,由于我绝不是Python专家,我觉得Python的某些部分不是惯用的 特别是,我为模块的用户提供了对DLL位置的控制。DLL在模块导入期间加载。我这样做是因为我想根据DLL的功能切换行为,我需要加载DLL以查询其行为 默认情况下,DLL加载依赖于DLL搜索路径的路径来定位DLL。我希望能够允许用户指定DLL的完整路径,如果他们希望选择特定的版本

我维护一个Python模块,该模块包装并公开DLL的功能(也由我维护)。与DLL的接口使用ctypes

多亏了ctypes的奇迹,这一切都非常有效。然而,由于我绝不是Python专家,我觉得Python的某些部分不是惯用的

特别是,我为模块的用户提供了对DLL位置的控制。DLL在模块导入期间加载。我这样做是因为我想根据DLL的功能切换行为,我需要加载DLL以查询其行为

默认情况下,DLL加载依赖于DLL搜索路径的路径来定位DLL。我希望能够允许用户指定DLL的完整路径,如果他们希望选择特定的版本


目前,我通过使用环境变量来实现这一点,但我认识到这是一种相当奇怪的方式。我要寻找的是一种规范的或惯用的Python方法,模块导入器可以将一些信息传递给模块,这些信息可以在模块导入时访问。

此代码取自此页面 它将一些路径添加到:

ALLDIRS = ['usr/local/pythonenv/PYLONS-1/lib/python2.5/site-packages']

import sys 
import site 

# Remember original sys.path.
prev_sys_path = list(sys.path) 

# Add each new site-packages directory.
for directory in ALLDIRS:
  site.addsitedir(directory)

# Reorder sys.path so new directories at the front.
new_sys_path = [] 
for item in list(sys.path): 
    if item not in prev_sys_path: 
        new_sys_path.append(item) 
        sys.path.remove(item) 
sys.path[:0] = new_sys_path 

您应该将加载DLL的时间推迟到它第一次实际使用的时间,并提供一个可选函数initialize:

_initialized=False
def initialize(path=None):
  if _initialized:
    if path:
      raise ValueError, "initialize called after first use"
    return
  if path is None:
    path = default_path
  load_dll(path)
  determine_features()
然后,在您提供的所有API中调用
initialized()
。这给了用户一个重写它的机会,但如果他们不重写,它将继续像今天一样工作(您甚至可以保留对环境变量的支持)

如果您愿意更改API,请使用类:

class DLLAPI:
  def __init__(self, path=None):
    ...

用户必须创建一个DLLAPI实例,可能传递也可能不传递DLL路径。这应该允许同时使用不同的DLL。

+1,使用最少的导入,具有处理更复杂内容的初始化功能。例如,pygame.init()+1感谢Martin。这肯定能完成工作。唯一的缺点是我必须在每个入口点调用惰性初始化例程。谢天谢地,我的入门点相对较少。@Martin我已经尝试过这种方法,我不希望它能轻易解决我的问题。很可能是我构建这个模块的整个方法都是错误的,但我将尝试进一步解释。DLL的功能确实需要在模块导入时知道。我的模块定义了各种类,这些类需要知道它们定义时的DLL功能(即导入时间)。所以,我仍然被困住了,但可能是我自己缺乏理解才是罪魁祸首。@David Heffernan:如果你想得到进一步的帮助,你必须编辑你的问题以提供更多细节。例如,具体需要如何更改类?(给出实际代码中的具体示例)。马丁:谢谢。马丁:我敢肯定,这一切都可以懒散地完成。我可能需要一点时间来准备好这样的代码。我想再做一点实验,把它精简到最基本的部分——我不想在那里扔一堵代码墙!谢谢你的建议,但这不是我想要的。我想我没有把我的问题说清楚。无论如何,还是谢谢你。