Python - запустить функцию при изменении папки - PullRequest
0 голосов
/ 15 мая 2018

Я хочу запускать свою функцию всякий раз, когда в моей папке происходят изменения.Здесь главное нормализовать новые файлы. Для этого мы сравниваем две мои папки: папку, в которой содержатся нормализованные файлы, и папку, в которую мы добавляем новые файлы и возвращаем список несопоставленных файлов, которые будут изменены нашей функцией нормализации.и поместите в папку нормализованных.

Вот мой код :

def normalize(c):
    PATH = path_to_file 
    fileNames = os.listdir(PATH)

    fileNames = c
    for file in fileNames:
        sfm = pd.read_csv(PATH + file, delimiter = ';', parse_dates=[[0, 1]], skiprows = 3)
  # other instructions then rewrite my new dataframe in my normalized folder
sfm.to_csv('.\dirnormalized'+str(file[:-4])+'.csv', sep=';', index=False, header=True)

def comparison():
    PATH = path_to_file 
    PATH_norm = path_to_norm
    fileNames = os.listdir(PATH)
    files = os.listdir(PATH_norm)
    fileNames = [file for file in fileNames if '.csv' in file]
    files = [fl for fl in files if '.csv' in fl]
    diff = [x for x in fileNames if x not in files]
    return diff

def change():

    logging.basicConfig(level=logging.INFO,
                        format='%(asctime)s - %(message)s',
                        datefmt='%Y-%m-%d %H:%M:%S')
# path_to_file and word_file are the same the only difference is that in path_to_file we have a back slash in the end in order to acces the files one by one 
    path = word_file
    event_handler = LoggingEventHandler()
    observer = Observer()
    observer.schedule(event_handler, path, recursive=True)
    observer.start()
    try:
        while True:
            time.sleep(1)
    except KeyboardInterrupt:
        observer.stop()
    observer.join()

def process(): 
    if(change()):
        c = comparison()
        normalize(c)
if __name__ == "__main__":
    import os 
    import time
    import logging
    from watchdog.observers import Observer
    from watchdog.events import LoggingEventHandler

    process()

Единственная проблема заключается в том, что в моей process() функции if() инструкция не передается другим, я вижу, когда добавляются новые файлы, что означает, что когда происходит изменение, но другие инструкции не выполняются, оно застревает на if().

Ответы [ 2 ]

0 голосов
/ 15 мая 2018

Проверьте это на наличие изменений в директории.

Используйте MS ReadDirectoryChanges API, предоставляемый через модуль win32file pywin32.

Мы используем его здесь, чтобы использовать вызов ReadDirectoryChangesW в режиме блокировки.

Функция возвращает список из двух кортежей, каждый из которых представляет действие и имя файла. Переименование всегда дает пару из двух кортежей; другие составные действия также могут дать список.

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")

При некотором редактировании это может легко достичь того, что вы хотите, так как winApi используется, что, вероятно, будет менее подвержено ошибкам.

Спасибо, Тим Голден.

0 голосов
/ 15 мая 2018

Последняя строка process(), а именно observer.join(), вероятно, заблокирует поток, предотвращая возврат функции.

Кроме того, управление оставляет функцию, возвращающую None, в результате чего оператор if никогда не выполняется.

...