Python 求大佬们解惑, os.path.exists() 判断路径总是返回 false 怎么解决?

未闻佳音 · 2022年05月26日 · 最后由 未闻佳音 回复于 2022年05月27日 · 7299 次阅读

源码如下:

import os
import time


def open_cmd(command):
    fp = os.popen(command)
    return fp


def export_dmp(drive_letter, dm_bin_path, sysdba, sysdba_password, host, port, dmp_dir, owner_and_schema):
    t = time.strftime('%Y%m%d%H%M%S', time.localtime(time.time()))
    file_name = t + '-' + owner_and_schema + '-exp'
    commands_dm = rf'commands'
    try:
        open_cmd(commands_dm)  # 源码中此处执行完后会生成一个dmp文件
    except Exception as err:
        print(err)
    dmp_file_path = os.path.join(dmp_dir, f'{file_name}.dmp')  # eg: D:/test/dm_sql/20220526112545-LSZ_INSIDE-exp.dmp
    # dmp_file_path = dmp_dir + file_name + '.dmp'
    # if os.path.exists(os.path.realpath(dmp_file_path)):       # false
    # if os.path.exists(dmp_file_path):                         # false
    return dmp_file_path, os.path.realpath(dmp_file_path)

如上所述, 判断始终是 false, 文件是实际存在的, 而且我把路径 D:/test/dm_sql/20220526112545-LSZ_INSIDE-exp.dmp 字符串直接拿去判断又能返回 True, 有点迷, 希望大佬们能帮我看看

最佳回复
未闻佳音 回复

试了下,os.popen 返回的是连接管道的文件对象,所以只要管道建立开始运行了,就会立即返回,不会等管道里面的命令执行完毕。
如果需要等待命令执行完毕,得给返回值加上 read() ,进行里面的值读取,读取完加上 close() 方法关闭文件对象。

一般建议用法是:

# 通过 with 让文件对象在结束 with 内代码执行时自动关闭
with os.popen("cmd") as p:
    # 把命令执行输出值记录到 return_value 变量中,后续使用
    return_value = p.read()

另外,看你这里应该没有获取返回值的需要,建议直接用 os.system() 可能更方便。

共收到 7 条回复 时间 点赞

好家伙, 试着加了句休眠, 解决了. 原来是判断太快了, 文件生成还没有完成. 我就说路径没问题的😂

time.sleep(0.5)
    if os.path.exists(dmp_file_path):
        return dmp_file_path, os.path.realpath(dmp_file_path)

有点奇怪,你的命令执行完正常不是文件已经生成完毕了么?

陈恒捷 回复

讲道理, 我开始也是这样觉得的, 所以开始一直没有找到问题所在. 后面我自己又写了一个定时内循环判断文件是否存在的方法, 效果如下, 证明原来的判断代码还是执行得太快了.

# time.sleep(0.5)
    # if os.path.exists(dmp_file_path):
    if get_dmp_path(os.path.realpath(dmp_file_path)):
        return dmp_file_path, os.path.realpath(dmp_file_path), dmp_log_path

os.popen 印象中好像是异步的,主进程如果要等待其执行结束,open_cmd 可能改为 return fp.read() 可以解决,可以试下

未闻佳音 回复

试了下,os.popen 返回的是连接管道的文件对象,所以只要管道建立开始运行了,就会立即返回,不会等管道里面的命令执行完毕。
如果需要等待命令执行完毕,得给返回值加上 read() ,进行里面的值读取,读取完加上 close() 方法关闭文件对象。

一般建议用法是:

# 通过 with 让文件对象在结束 with 内代码执行时自动关闭
with os.popen("cmd") as p:
    # 把命令执行输出值记录到 return_value 变量中,后续使用
    return_value = p.read()

另外,看你这里应该没有获取返回值的需要,建议直接用 os.system() 可能更方便。

北溟 回复

嗯嗯 用 popen 之前有了解过 我都试试吧 谢谢了

陈恒捷 回复

嗯嗯,大佬说的很有道理,谢谢了。我都试试吧。之所以不用 os.system 是因为这个控制台会输出一大堆我不想看的东西😳

未闻佳音 关闭了讨论 05月30日 16:46
需要 登录 后方可回复, 如果你还没有账号请点击这里 注册