参数化导入语句

时间:2011-01-22 09:44:42

标签: python

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

由于ctypes的奇迹,这一切都非常有效。但是,由于我不是Python专家,因此我认为Python的某些部分不是惯用的

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

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

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

2 个答案:

答案 0 :(得分:5)

您应该将DLL加载到第一次实际使用的位置,并提供一个可选的函数初始化:

_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 :(得分:1)

此代码来自此页http://code.google.com/p/modwsgi/wiki/VirtualEnvironments 它增加了一些探索途径:

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