Runscript-Pythonスクリプトを実行するためのユーティリティ

多くの人が次の状況に精通していると思います。 プロジェクトには、時々実行する必要があるさまざまなアクションがあります。 アクションごとに、個別のpythonスクリプトを作成します。 遠くまで登らないように、スクリプトをプロジェクトのルートに配置します。 しばらくすると、プロジェクトのルートディレクトリ全体にこれらのスクリプトが散らばり、別のディレクトリに配置することになります。 今、問題が始まります。 この新しいディレクトリを含むスクリプトへのパスをPythonインタープリターに伝えた場合、プロジェクトのルートにあるパッケージのインポートはスクリプト内では機能しません。 プロジェクトのルートはsys.pathにはありません。 この問題はいくつかの方法で解決できます。 プロジェクトのルートを追加することにより、各スクリプトのsys.pathを変更できます。 スクリプトを実行する前にsys.pathを変更するスクリプトを実行するユーティリティを作成するか、プロジェクトのルートに配置することができます。 他の何かを考えることができます。 私は毎回車輪の再発明にうんざりしていて、乗馬を楽しむランスクリプトバイクを作成しました。



pipを使用してライブラリをインストールできます。



$ pip install runscript


runscriptライブラリをインストールすると、スクリプトを実行できる新しいrun consoleコマンドがシステムに取得されます。 デフォルトでは、runコマンドは現在のディレクトリのスクリプトサブディレクトリでスクリプトを検索します。



簡単な例を見てみましょう。 スクリプトディレクトリを作成します。 空のスクリプト/ __ init__.pyファイルを作成し、このディレクトリをPythonパッケージに変換します。 ここで、次の内容のscript / preved.pyファイルを作成します。



def main(**kwargs): print('Preved, medved!')
      
      







スクリプトの準備ができました。 これで実行できます:



$保存済み

ほらほら!


やった! スクリプトは動作します。 runscriptライブラリが行うのはそれだけです。 私は真剣です:) runコマンドは、コマンドラインで名前を渡したファイルからメイン関数を開始します。 そのような単純な機能でさえ非常に便利であることが判明しました。 各プロジェクトでrunユーティリティを使用していることに驚いた。 どこにでも実行する必要がある単純なスクリプトがあります。



時間が経つにつれて、runユーティリティは多くの有用なユーティリティを取得しました。これについては、後で説明します。



コマンドラインからパラメーターを取得する



コマンドラインを介してスクリプトにパラメーターを渡すには、スクリプト内のsetup_arg_parser関数でこれらのパラメーターを記述する必要があります。 この関数は、入力としてArgumentParserオブジェクトを受け取り、そこに必要なオプションを追加できます。 さらに、スクリプトが呼び出されると、コマンドラインパラメーターの値がメイン関数に渡されます。 サンプルスクリプト:



 def setup_arg_parser(parser): parser.add_argument('-w', '--who', default='medved') def main(who, **kwargs): print('Preved, {}'.format(who))
      
      





以下を開始します。



$保存済み

焼き付け

$ run preved -w anti-medved

防腐、防腐


メイン関数がコマンドラインオプションを受け取った方法に注意してください—通常の名前付きパラメーターの形で。 ** kwargsは常に指定する必要があります。 必要なパラメータに加えて、ユーティリティ実行のすべてのグローバルパラメータの値が転送されます(それらについては以下をお読みください)。



Django Activation



コンソールスクリプトでDjangoフレームワークを使用しようとした場合、何かを行う必要があることがわかります。そうしないと何も起こりません。 設定を行うモジュールへのパスを含む環境変数DJANGO_SETTINGS_MODULEを作成することです。 通常、pythonスクリプトで次の行を追加します。



 import os os.environ['DJANGO_SETTINGS_MODULE'] = 'settings'
      
      





django 1.7以降では、実行する必要があります



 import django django.setup()
      
      





runを介して実行されるスクリプトでこれらのアクションを自動的に実行するには、次の設定を含むrun.iniという名前のファイルをプロジェクトルートに作成する必要があります。



 [global] django_settings_module = settings django_setup = yes
      
      







プロファイリング



スクリプトを呼び出すときに--profileキーを追加すると、スクリプトの動作をプロファイリングした結果を含むファイルが取得され、kcachegrindで表示できます。 結果はvar / <script_name> .prof.outディレクトリに保存されるため、必ずこのディレクトリを作成してください。 プロファイル結果をkcachegrind形式で保存するために必要なpyprof2calltreeモジュールもインストールする必要があります。



$ run preved --profile

焼き付け

$ ls var /

preved.prof.out



スクリプト検索場所の設定



デフォルトでは、runユーティリティはgrab.scriptとscriptの2つのパッケージでスクリプトを探します。 多くのサイト解析プロジェクトではgrab.scriptパッケージからcrawlコマンドを実行するため、grab.scriptパッケージがこのリストに追加されます。 スクリプトを検索する場所を変更する必要がある場合は、run.iniファイルに次の設定を作成します。



 [global] search_path = package1.script,foo,bar
      
      





ここで、run prevedコマンドを実行すると、runユーティリティは次の順序でprevedモジュールをインポートしようとします。







ロックファイルを使用する



スクリプトの複数のインスタンスの同時操作を禁止することが必要な場合があります。 たとえば、cronを使用して1分ごとにスクリプトを呼び出し、スクリプトの複数のコピーが同時に機能しないようにしたい場合があります。 --lock-keyオプションを使用すると、var / runディレクトリに作成されるロックファイルの名前を渡すことができます。 たとえば、--lock-key fooはvar / run / foo.lockファイルを作成します。



ロックファイルの名前を設定する別の方法は、スクリプト内でget_lock_key関数を作成することです。 その作業の結果は、実行ユーティリティによってロックファイルの名前を生成するために使用されます。 この関数は、スクリプトに渡されるパラメーターに応じてロックファイル名を生成する場合に役立ちます。



 import time def get_lock_key(who, **kwargs): return 'the-{}-lock'.format(who) def setup_arg_parser(parser): parser.add_argument('-w', '--who', default='medved') def main(who, **kwargs): print('Preved, {}'.format(who)) time.sleep(1)
      
      





スクリプトの2つのコピーを同時に起動し、以下を確認します。



$ preved -w anti-medvedを実行&run preved -w anti-medvedを実行

[1] 25,277

ファイルをロックしようとしています:var / run / the-anti-medved-lock.lock

防腐、防腐

ファイルをロックしようとしています:var / run / the-anti-medved-lock.lock

ファイルvar / run / the-anti-medved-lock.lockはすでにロックされています。 終了します。

[1] +実行完了-w anti-medved





runscriptライブラリの主な機能について話しました それがあなたのお役に立てば幸いです。



ライブラリの操作について質問がある場合は、いつでもソースコードを見ることができます。これは現在非常に小さいものです。github.com / lorien / runscript / blob / master / runscript / cli.py



All Articles