【问题标题】:Passing a string to module "once"将字符串传递给模块“一次”
【发布时间】:2015-04-18 16:48:58
【问题描述】:

我的问题很简单:我只需要将一个字符串(路径和文件名)传递给一个模块一次,以供该模块中的函数使用。换句话说,函数需要一个路径(和文件名)才能工作,而且每次调用函数时都传递该字符串是不切实际的。

有没有一种方法可以让我真正传递一个字符串一次(可能稍后在脚本中更改它)并以某种方式将其保存在模块中以供以后使用?

【问题讨论】:

  • 你可以只使用某种“init_module()”函数来设置模块内的共享变量

标签: python python-2.7 python-module


【解决方案1】:

您可以简单地在模块中设置一个全局:

variable_to_use = None

def funcA():
    if variable_to_use is None:
        raise ValueError('You need to set module.variable_to_use before using this function')
    do_something_with(variable_to_use)

variable_to_use 对模块中的所有代码都是全局的。然后其他代码可以这样做:

import module_name

module_name.variable_to_use = 'some value to be used'

但是,不要试图使用from module_name import variable_to_use,因为这会创建一个本地引用,然后将其反弹,保持模块全局不变。

您可以将该全局设置封装在一个函数中:

def set_variable_to_use(value):
    global variable_to_use
    variable_to_use = value

并使用该函数而不是直接设置模块全局。

【讨论】:

  • 这正是我所做的!我使用了一个全局路径字符串并将其作为参数传递给我的函数。
  • @MalikBrahimi:不,你没有。您设置函数默认值。 那不是一回事。见"Least Astonishment" in Python: The Mutable Default Argument
  • @MalikBrahimi:测试你的代码,你会发现它不是那样工作的arg 默认值设置一次,当定义函数时,例如导入模块时。然后您不能更改 path 并期望这些默认值会效仿,因为 它们不会再次设置
  • 谢谢,这正是我所需要的。我其实不知道一个变量会是模块内部的全局变量。
【解决方案2】:

一种选择是将函数添加到类中,并使用对象实例来保存不同的可重用值。

class Foo():
    def __init__(self, fpath, fname):
        self.fpath = fpath
        self.fname = fname

    def funcA(self):
        print "do something with the path: {}".format(self.fpath)

    def funcB(self):
        print "do something with the filename: {}".format(self.fname)

if __name__ == '__main__':
    my_object = Foo("/some/path/", "some_filename")
    my_object.funcA()
    my_object.funcB()

【讨论】:

    【解决方案3】:

    您可以在模块中添加设置功能,例如

    import functools
    
    _path = None
    
    def setup(path):
        global _path
        _path = path
    
    def setup_required(func):
        @functools.wraps(func)
        def wrapped(*args, **kwargs):
            global _path
            if _path is None:
                raise RuntimeError('setup required')
            return func(*args, **kwargs)
        return wrapped
    
    @setup_required
    def foo(...):
        with open(_path) as f:
            ....
    
    @setup_required
    def bar(...):
        ...
    

    最好将依赖于路径的函数包装在类中,并将配置的对象作为依赖项注入到使用要从模块公开的 api 的代码中。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-12-10
      • 1970-01-01
      • 1970-01-01
      • 2013-10-21
      • 2017-12-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多