代码之家  ›  专栏  ›  技术社区  ›  Mark

导入时传递变量

  •  29
  • Mark  · 技术社区  · 15 年前

    例如,我使用rpy2:

    import rpy2.robjects as robjects
    
    PATH_TO_R_SOURCE = ## I need to pass this
    robjects.r.source(PATH_TO_R_SOURCE, chdir = True) ## this takes time
    
    class SomeClass:
      def __init__(self, aCurve):
        self._curve = aCurve
    
      def processCurve(self):
        robjects.r['someRFunc'](robjects.FloatVector(self._curve))
    

    我是不是在创建一个我调用的模块级函数来完成这项工作?

    import someClass
    someClass.sourceRStuff(PATH_TO_R_SOURCE)
    x = someClass.SomeClass([1,2,3,4])
    etc...
    
    8 回复  |  直到 8 年前
        1
  •  31
  •   nmichaels    15 年前

    拥有module init函数并非闻所未闻。Pygame为sdl初始化函数做这个。所以是的,你最好的选择是

    import someModule
    someModule.init(NECESSARY_DATA)
    x = someModule.someClass(range(1, 5))
    
        2
  •  18
  •   ADTC Adam Rosenfield    8 年前

    我不得不为我的项目做类似的事情。如果您不想依赖调用脚本来运行初始化函数,那么可以添加自己的Python内置,然后在运行时所有模块都可以使用它。

    请注意将您的内置命名为不太可能引起名称空间冲突的唯一名称(例如 myapp_myvarname

    import __builtin__
    __builtin__.myapp_PATH_TO_R_SOURCE = 'path.to.r.source'
    import someClass
    

    someClass模块.py

    import rpy2.robjects as robjects
    import __builtin__
    
    if hasattr(__builtin__, "myapp_PATH_TO_R_SOURCE"):
        PATH_TO_R_SOURCE = __builtin__.myapp_PATH_TO_R_SOURCE
    else:
        PATH_TO_R_SOURCE = ## Some default value or Null for Exception handling
    robjects.r.source(PATH_TO_R_SOURCE, chdir = True)
    
    ...
    

    对于可能有默认值但希望在导入时允许重写的变量,这一点很好。如果 __builtin__

    see my other answer .

        3
  •  10
  •   Aaron D    9 年前

    如果只有一个配置项需要设置,那么我发现重写python __builtin__ 很好地工作,但这是 "Monkey patching"

    对于项目中的多个配置项非常有用的一种更简洁的方法是创建一个单独的配置模块,在功能模块导入之前,该模块首先由包装代码导入,并在运行时设置项。此模式通常用于其他项目。

    PATH_TO_R_SOURCE   = '/default/R/source/path'
    OTHER_CONFIG_ITEM  = 'DEFAULT'
    PI                 = 3.14
    

    mymodule/\uuu init\uuuuuuuuy.py:

    import myconfig
    
    PATH_TO_R_SOURCE = myconfig.PATH_TO_R_SOURCE
    robjects.r.source(PATH_TO_R_SOURCE, chdir = True) ## this takes time
    
    class SomeClass:
      def __init__(self, aCurve):
        self._curve = aCurve
    
    if myconfig.VERSION is not None:
      version = myconfig.VERSION
    else:
      version = "UNDEFINED"
    
    two_pi = myconfig.PI * 2
    

    您可以通过包装器在运行时更改模块的行为:

    运行.py:

    import myconfig
    
    myconfig.PATH_TO_R_SOURCE = 'actual/path/to/R/source'
    myconfig.PI = 3.14159
    # we can even add a new configuration item that isn't present in the original myconfig:
    myconfig.VERSION="1.0"
    
    import mymodule
    print "Mymodule.two_pi = %r" % mymodule.two_pi
    print "Mymodule.version is %s" % mymodule.version
    

    > Mymodule.two_pi = 6.28318
    > Mymodule.version is 1.0
    
        4
  •  4
  •   leoluk    15 年前

    无法在导入时传递变量。

    一些想法:

    • 使模块使用inspection从调用模块获取变量;不是很pythonic
    • 对模块使用Init函数,这是最好的方法
        5
  •  3
  •   tiho Contango    13 年前

    可以实现您的目标的两个其他选项(尽管init()函数可能更简洁):

    • 使用环境变量
    • 使用一个单独的模块M来保存导入程序将设置的变量。然后导入的模块可以知道在哪里找到M,也可以依赖系统元路径为了得到它。
        6
  •  2
  •   aaronasterling    15 年前

    不,你不必拘泥于模块级函数,它可能是最好的选择。你也可以用内置的 staticmethod classmethod 使之成为 someSclass

    这是有道理的 只有 如果除了 someClass 在没有初始化的情况下是可用的,我仍然认为模块级函数更好。

        7
  •  2
  •   SarcasticSully    7 年前

    sys.argv[1] = "argument 1"
    sys.argv[2] = "argument 2"
    execfile("/path/to/dependency.py")  #depreciated in python 3.x
    

    第二种方法是将参数放入一个外部临时文件中,然后从依赖项中的该文件读取。

        8
  •  0
  •   Escualo    15 年前

    您能从实现延迟加载的代理中获益吗?

    “查看活动状态” Lazy Module Imports “食谱。