【问题标题】:How to run Python method only once, durning the program life cycle?如何在程序生命周期中只运行一次 Python 方法?
【发布时间】:2019-08-01 12:53:25
【问题描述】:

我已经构建了一个 Python Flask REST API,它可以响应 POST 请求。每次调用端点时,都会读取来自服务器的文件。我想知道有什么方法可以只读取一次文件吗?

我希望它只有在程序启动后才能从文件中读取。目前,每次调用“/test”端点时都会读取文件。

这是一个控制器的例子:

@app.route('/test', methods=['POST'])
def test(data):
    file_content = Data.readFile()
    ...
    "Here do something with the file content and data"

这是Data.py的内容:

def readFile():
    with open(os.getcwd() + '/csv_files/' + config.WORDS, encoding="utf-8-sig", mode='r') as f:
        csv_reader = csv.reader(f, delimiter=';')
        file_content = [row[0] for row in csv_reader]
    return file_content

我知道在 Java Spring 中你可以使用@PostConstruct 或@Configuration。 Python中有类似的东西吗?

【问题讨论】:

  • 除非我遗漏了什么,否则您可以将对 readFile 的调用从路由移动到“全局”空间,即在 app 的定义下
  • 这类似于memoization,但您可能可以做一些更简单的事情,比如拥有一个全局变量。
  • 视情况而定。它会时不时地改变吗?如果是这样,那么您可以通过缓存返回文件内容的方法来使用具有超时的 Redis。 pythonhosted.org/Flask-Cache/#caching-other-functions 。注意:这可能比用户使用全局变量慢,但是这允许添加超时并且总体上看起来更干净。
  • 你在看python中的单例模式实现吗
  • 你签出Sessions了吗?

标签: python flask flask-restful


【解决方案1】:

你可以为此创建一个闭包函数。

# Data.py
def read_file():
    # the variable `read_file` is being modified inside the function
    # ignoring the global declaration will create a local variable read_file
    global read_file

    with open(os.getcwd() + '/csv_files/' + config.WORDS, encoding="utf-8-sig", mode='r') as f:
        csv_reader = csv.reader(f, delimiter=';')
        file_content = [row[0] for row in csv_reader]

    def inner():
        return file_content

    # read file is a global variable 
    # because it is declared as a function in the global scope
    # we are modifying it here and monkey patching it with `inner`
    # subsequent calls to `read_file` will inherently call `inner`
    read_file = inner

    # for the first time the function is called
    return file_content

第一次调用read_file()时,文件被打开,file_content被加载到变量中,变量read_fileinner函数替换。
对于后续的方法调用,file_content 的值只是由inner 函数返回。

【讨论】:

    【解决方案2】:

    更改控制器,使文件数据已在函数外部读取。

    pre_file_content = Data.readFile()
    @app.route('/test', methods=['POST'])
    def test(data):
        file_content = pre_file_content
        ...
        "Here do something with the file content and data"
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-22
      • 2015-12-16
      相关资源
      最近更新 更多