python一个脚本循环两次

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了python一个脚本循环两次相关的知识,希望对你有一定的参考价值。

参考技术A 我的python脚本中有一个问题,for循环有时会重复2次。就像它应该每个字母写一次,有时(我看到它通常在一个“”之前)它会写两次。(很多变量都是用法语写的,但这并不重要)代码用于在游戏Raft中在钢琴上播放歌曲(顶部的数字系列),因此我必须将每个数字分配给键盘的一个键。你可以在你的电脑上使用代码,因为按下的键是在终端上打印的(注)。我的问题是它不能正确播放,有时会重复同一个键。 参考技术B def _interactiveMode(command): if raw_input('Execute command ' + com

当文件更新时,用于监视目录的 Python 脚本会触发两次。为啥?

【中文标题】当文件更新时,用于监视目录的 Python 脚本会触发两次。为啥?【英文标题】:Python script to monitor a directory triggers twice when a file is updated. Why?当文件更新时,用于监视目录的 Python 脚本会触发两次。为什么? 【发布时间】:2018-11-06 13:30:37 【问题描述】:

短版: 我编写/改编的 Python 脚本用于监视目录的更改,在修改文件时会触发两次。为什么?

长版:

我正在编写一些 Python 代码来监视目录及其子目录的更改。

我从http://timgolden.me.uk/python/win32_how_do_i/watch_directory_for_changes.html 的“使用 ReadDirectoryChanges API”部分中的示例开始

(出于企业 IT 的原因,我不适合使用 Python Watchdog 包。)

从那里的例子中剪切和粘贴:

import os

import win32file
import win32con

ACTIONS = 
  1 : "Created",
  2 : "Deleted",
  3 : "Updated",
  4 : "Renamed from something",
  5 : "Renamed to something"

# Thanks to Claudio Grondi for the correct set of numbers
FILE_LIST_DIRECTORY = 0x0001

path_to_watch = "."
hDir = win32file.CreateFile (
  path_to_watch,
  FILE_LIST_DIRECTORY,
  win32con.FILE_SHARE_READ | win32con.FILE_SHARE_WRITE | win32con.FILE_SHARE_DELETE,
  None,
  win32con.OPEN_EXISTING,
  win32con.FILE_FLAG_BACKUP_SEMANTICS,
  None
)
while 1:
  #
  # ReadDirectoryChangesW takes a previously-created
  # handle to a directory, a buffer size for results,
  # a flag to indicate whether to watch subtrees and
  # a filter of what changes to notify.
  #
  # NB Tim Juchcinski reports that he needed to up
  # the buffer size to be sure of picking up all
  # events when a large number of files were
  # deleted at once.
  #
  results = win32file.ReadDirectoryChangesW (
    hDir,
    1024,
    True,
    win32con.FILE_NOTIFY_CHANGE_FILE_NAME |
     win32con.FILE_NOTIFY_CHANGE_DIR_NAME |
     win32con.FILE_NOTIFY_CHANGE_ATTRIBUTES |
     win32con.FILE_NOTIFY_CHANGE_SIZE |
     win32con.FILE_NOTIFY_CHANGE_LAST_WRITE |
     win32con.FILE_NOTIFY_CHANGE_SECURITY,
    None,
    None
  )
  for action, file in results:
    full_filename = os.path.join (path_to_watch, file)
    print full_filename, ACTIONS.get (action, "Unknown")

一般来说,这个例子运行良好,可以做我想做的事。特别是,它在创建文件时工作正常。然而,当一个文件被编辑/修改/更新时,最后的 print 语句(代表我真正想做的动作)会触发两次。

为什么会这样?以及如何防止它,或者至少解决它?我有过的最好的想法是第一次为 True 而第二次为 False 的标志。然而,这感觉就像一个杂牌。

关于一个可能相关的问题,我在哪里可以找到有关 win32con 包和 Microsoft ReadDirectoryChanges API 的文档?我做了一些谷歌搜索,但没有找到任何我认为有用的东西。

哦,是的 - 我在 Windows 7 Enterprise 上运行 Python 3.5.1。

编辑: 好的,看起来我所看到的可能是 ReadDirectoryChangesW() 中固有的。我发现这个 *** 线程似乎基本上是相同的问题,除了原始海报使用的是 C++,而不是 Python。 C++ WinApi: ReadDirectoryChangesW() Receiving Double Notifications

【问题讨论】:

您正在关注大小变化和最后一次写入变化。编辑文件时,这两个参数可能会一起更改。因此它会触发两次。如果您不处理其他程序打开的文件,请尝试删除大小观察器。 啊。呃。我在想,如果任何一个条件为真,我会得到一个响应,但我相信你是正确的 - 对于每一个为真的条件,我都会得到一个响应。感谢您的帮助! 好的,这可能比我们想象的要复杂。我已经注释掉了 FILE_NOTIFY_CHANGE_SIZE 和 FILE_NOTIFY_CHANGE_ATTRIBUTES 行。但是,打印语句仍然触发了两次。奇怪的是,“结果”变量只列出了一个项目:[(3, 'New Text Document.txt'] 我更新了我的评论 - 不小心按了“Enter”。我更新的推荐是否回答了您的问题?而且它是同一个文件 - 我只是在编辑现有行或添加新行。 很遗憾,我不能去聊天。又是企业 IT。 【参考方案1】:

我没有安装 python 2.7,所以我无法通过查看这部分来自己测试

 win32con.FILE_NOTIFY_CHANGE_FILE_NAME |
 win32con.FILE_NOTIFY_CHANGE_DIR_NAME |
 win32con.FILE_NOTIFY_CHANGE_ATTRIBUTES |
 win32con.FILE_NOTIFY_CHANGE_SIZE | #this will change when someone writes or deletes to the file
 win32con.FILE_NOTIFY_CHANGE_LAST_WRITE |#this will change when someone modifies the file
 win32con.FILE_NOTIFY_CHANGE_SECURITY,

看看这两种情况是如何被同一个动作触发的?这可能是触发您行为的原因,请尝试删除两者之一

编辑以澄清下面的 cmets:

要了解每种更改的行为,请尝试以下操作:

results = 
results['FName_Change'] = win32file.ReadDirectoryChangesW (
                        hDir,
                        1024,
                        True,
                        win32con.FILE_NOTIFY_CHANGE_FILE_NAME,
                        None,
                        None
                      )
results['DName_Change'] = win32file.ReadDirectoryChangesW (
                        hDir,
                        1024,
                        True,
                         win32con.FILE_NOTIFY_CHANGE_DIR_NAME, 
                        None,
                        None
                        )
  results['Attributes_Change'] = win32file.ReadDirectoryChangesW (
                        hDir,
                        1024,
                        True,
                         win32con.FILE_NOTIFY_CHANGE_ATTRIBUTES, 
                        None,
                        None

通过操作此数据结构,您应该能够从更改中提取行为类型信息

【讨论】:

谢谢。我确定你是对的。正如我上面评论的那样,我想如果任何条件为真,我会得到一个响应,但我会为每个条件都得到一个响应。 这里我能想到的唯一问题是:他正在查看另一个进程打开的日志文件。该文件将继续增长,但我不确定最后一次写入是否会随着文件保持打开而改变。 对于我的用例,这不是问题。我正在查看由另一个程序创建的数据文件,而不是由另一个程序更新的日志文件。创建文件后,我想处理它。如果文件已更新,则同上,这通常是手动完成以纠正数据输入问题。 您可以做的是将 results 与单独的 win32file.ReadDirectoryChangesW() 调用拆分为每个项目/通知类型,然后单独存储它们,这样您就可以更好地了解更改是什么实际制作中 “results”只有一个条目:[(3, 'New Text Document.txt']。没有什么可以拆分的。还是我误解了你?

以上是关于python一个脚本循环两次的主要内容,如果未能解决你的问题,请参考以下文章

Python 应用闭包思路动态生成unittest执行脚本---分析问题,解决问题,记录填坑。

如何使用'for'循环将新变量传递给python脚本

Python telnet 脚本循环

为啥这个 Python 代码会运行两次? [复制]

python循环控制间隔。

if控制器+循环控制器+计数器,控制接口分支