Python Windows目录mtime:如何检测包目录中新文件?

0 投票
4 回答
714 浏览
提问于 2025-04-15 12:51

我正在为WHIFF开发一个自动重载的功能,目的是让你不需要频繁重启HTTP服务器,理想情况下是永远不需要。

我有一段代码可以在包目录下添加文件时重新加载一个叫“location”的模块。但是这段代码在Windows XP上不工作。我该怎么解决这个问题呢?我觉得问题可能出在getmtime(dir)这个函数上,因为在Windows上,当目录内容变化时,它不会更新。我其实不想每次访问包的时候都去比较os.listdir(dir)和上次的目录内容...

                if not do_reload and hasattr(location, "__path__"):
                    path0 = location.__path__[0]
                    if os.path.exists(path0):
                        dir_mtime = int( os.path.getmtime(path0) )
                        if fn_mtime<dir_mtime:
                            print "dir change: reloading package root", location
                            do_reload = True
                            md_mtime = dir_mtime

在这段代码中,“fn_mtime”是上次(重新)加载时记录的修改时间。

...我补充了一条评论:我想出了一个解决办法,可能会有效,但我不太喜欢这个方法,因为它涉及到代码生成。我动态生成一段代码来加载模块,如果失败了,就在重载后再试一次。这个方法还没有测试过。

GET_MODULE_FUNCTION = """
def f():
    import %(parent)s
    try:
        from %(parent)s import %(child)s
    except ImportError:
        # one more time...
        reload(%(parent)s)
        from %(parent)s import %(child)s
    return %(child)s
"""

def my_import(partname, parent):
    f = None # for pychecker
    parentname = parent.__name__
    defn = GET_MODULE_FUNCTION % {"parent": parentname, "child": partname}
    #pr "executing"
    #pr defn
    try:
        exec(defn) # defines function f()
    except SyntaxError:
        raise ImportError, "bad function name "+repr(partname)+"?"
    partmodule = f()
    #pr "got", partmodule
    setattr(parent, partname, partmodule)
    #pr "setattr", parent, ".", partname, "=", getattr(parent, partname)
    return partmodule

欢迎其他建议。我对此不太满意...

4 个回答

0

我不太明白你的问题...

你是在对一个文件夹还是一个单独的文件使用getmtime()这个函数呢?

0

关于你第一段代码,有两点让我有点担心:

  • 你把从getmtime得到的浮点数转换成了整数。根据这段代码运行的频率,你可能会得到不太可靠的结果。

  • 在代码的最后,你把dir_mtime的值赋给了一个叫md_mtime的变量。而你用来比较的fn_mtime似乎没有更新。

2

好久不见。我不太确定你具体在做什么,但你的代码可以等同于:

GET_MODULE_FUNCTION = """
def f():
    import %(parent)s
    try:
        from %(parent)s import %(child)s
    except ImportError:
        # one more time...
        reload(%(parent)s)
        from %(parent)s import %(child)s
    return %(child)s
"""

用下面的方式来执行:

defn = GET_MODULE_FUNCTION % {"parent": parentname, "child": partname}
exec(defn)

根据文档,假设parentname是一个包的名字,而partname是这个包里一个模块的名字(如果partname是parentname包的顶层名字,比如一个函数或类,你需要在最后用getattr来获取):

import sys

def f(parentname, partname):
    name = '%s.%s' % (parentname, partname)
    try:
        __import__(name)
    except ImportError:
        parent = __import__(parentname)
        reload(parent)
        __import__(name)
    return sys.modules[name]

不需要用exec或者其他奇怪的东西,只需适当地调用这个 f

撰写回答