私はこの質問に興味があり、著者のインド起源に怖がらない人に尋ねます 。
設置
PIPから完成版を入手できます。
$ pip install watchdog
PIP自体は、python-pipパッケージ、port devel / py-pipなどとしてインストールされます。
または、setup.pyを使用してソースからビルドします。
すべては、 元のマニュアルで十分に詳細に説明されています 。 確かに、バージョン0.5.4の説明があり、現在は0.6.0が関連しています。 ただし、全体の違いは、著作権の編集と4つのスペースのインデントを2のインデントに置き換えることです。「Googleコードスタイル」:)
一般に、Python自体のバージョンおよびターゲットプラットフォームには、アセンブリのかなりの数の機能があります。 これらはすべて上記のリンクで説明されていますが、必要に応じて、ロシア語で簡単に記事に追加します。
さらに、互換性のないOSでモジュールを構築することもできますが、その後、フォールバック実装が有効になり、FS構造の「キャスト」とその後の比較が行われます。 おそらくこれは誰かがそのような問題を解決するときにやったことです:)
私自身はubuntu 11.4とfreebsd-8.2リリースでビルドしようとしましたが、アセンブリと操作に問題はありませんでした。
基本的な例
ファイルとディレクトリの作成、削除、名前の変更に関連する特定のパス/パス/から/への変更に関心があるとします。
接続します:
from watchdog.observers import Observer from watchdog.events import FileSystemEventHandler
Observerクラスは、OSの機能に基づいて/observers/__init__.pyで選択されるため、何を選択するかを自分で決める必要はありません。
FileSystemEventHandlerクラスは、変更イベントハンドラーの基本クラスです。 彼はあまり知りませんが、彼の子孫を教えます:
class Handler(FileSystemEventHandler): def on_created(self, event): print event def on_deleted(self, event): print event def on_moved(self, event): print event
メソッドの完全なリストは、FileSystemEventHandler.dispatch自体で見ることができます:on_modified、on_moved、on_created、on_deleted。
すべてを開始します。
observer = Observer() observer.schedule(Handler(), path='/path/to/smth', recursive=True) observer.start()
Observerはthreading.Threadの比較的遠い子孫です。それぞれ、start()を呼び出した後、変更を監視するバックグラウンドスレッドを取得します。 そのため、スクリプトがすぐに終了した場合、賢明なことは何も得られません。 期待の実装は、主に実際のプロジェクトでのモジュールのアプリケーションに依存しますが、今では松葉杖を作ることができます:
try: while True: time.sleep(0.1) except KeyboardInterrupt: observer.stop() observer.join()
Ctrl + C(SIGINT)が到着するまで、FSの変更のイベントを待っています。その後、スレッドを終了し、完了するまで待機します。
スクリプトを実行し、次のように進みます。
# mkdir foo # touch bar # mv bar baz # cd foo/ # mkdir foz # mv ../baz ./quz # cp ./quz ../hw # cd .. # rm -r ./foo # rm -f ./*
スクリプトの出力には次のものがあります。
<DirCreatedEvent: src_path=/path/to/smth/foo> <FileCreatedEvent: src_path=/path/to/smth/bar> <FileMovedEvent: src_path=/path/to/smth/bar, dest_path=/path/to/smth/baz> <DirCreatedEvent: src_path=/path/to/smth/foo/foz> <FileMovedEvent: src_path=/path/to/smth/baz, dest_path=/path/to/smth/foo/quz> <FileCreatedEvent: src_path=/path/to/smth/hw> <FileDeletedEvent: src_path=/path/to/smth/foo/quz> <DirDeletedEvent: src_path=/path/to/smth/foo/foz> <DirDeletedEvent: src_path=/path/to/smth/foo> <FileDeletedEvent: src_path=/path/to/smth/hw>
イベントフィールドのHandlerクラスのメソッドは、watchdog / events.pyにリストされているFileSystemEventの子孫です 。
誰もがプロパティsrc_path、is_directory、event_type(「作成済み」、「削除済み」など)を持っています。 移動したイベントの場合、dest_pathプロパティが追加されます。
まあ、あなたは他に何もしたくない場合...他に何かありますか?
まず、 FileSystemEventHandlerの子孫があります。
- PatternMatchingEventHandler
- RegexMatchingEventHandler
- LoggingEventHandler
PatternMatchingEventHandlerを使用して、ルールとマスクに名前が一致するFSノードでのみイベントを受信できます。
- *任意の文字
- ? 任意の単一の文字
- [seq]指定された任意の単一文字
- [!seq]指定されていない任意の単一文字
ルールは、作成時に設定されます。
class Handler(PatternMatchingEventHandler): pass event_handler = Handler( patterns = ['*.py*'], ignore_patterns = ['cache/*'], ignore_directories = True, case_sensitive = False ) observer = Observer() observer.schedule(event_handler, path='/home/LOGS/', recursive=True)
RegexMatchingEventHandlerは同じことを行いますが、コンストラクターで明示的な正規表現式を使用します。
class Handler(RegexMatchingEventHandler): pass event_handler = Handler( regexes = ['\.py.?'], ignore_regexes = ['cache/.*'], ignore_directories = True, case_sensitive = False )
その結果、PatternMatchingEventHandlerはパターンを内部で通常のパターンに変換するため、このようなオーバーヘッドが存在するため、動作が遅くなります。
最後に、LoggingEventHandlerはlogging.info()を介してすべてを記録します。
-それだけです。 たぶん誰かが役に立つでしょう。
PS
(およびその子)にアスキー名のないフォルダー/ファイルが含まれるディレクトリを監視する場合、ウォッチドッグの深さで例外exceptions.UnicodeEncodeErrorが発生します。 Linux(inotify)では、 watchdog.observers.inotify.Inotify._add_watchで発生します。
その理由は、ASCIIエンコーディングでコンテンツを読み取ることです。
状況を修正するには、メソッドにパッチを適用できます。
from watchdog.observers.inotify import Inotify _save = Inotify._add_watch Inotify._add_watch = lambda self, path, mask: _save(self, path.encode('utf-8'), mask)
元の文字列の例と、encode()の処理前後のそのrepr()を次に示します。
/home/atercattus/.wine/drive_c/users/Public/ u'/home/atercattus/.wine/drive_c/users/Public/\u0420\u0430\u0431\u043e\u0447\u0438\u0439 \u0441\u0442\u043e\u043b' '/home/atercattus/.wine/drive_c/users/Public/\xd0\xa0\xd0\xb0\xd0\xb1\xd0\xbe\xd1\x87\xd0\xb8\xd0\xb9 \xd1\x81\xd1\x82\xd0\xbe\xd0\xbb'