2017-09-08 14 views
0

メインスクリプトからInsert_APIを実行するためにSubprocess呼び出しを使用しています。挿入する値はリストに格納されています。サブプロセス呼び出し中に引数としてリストを渡す必要があります。引数が文字列でなければならないと私はエラーを出します。私はstr(list)を作成すると動作しますが、Insertはリストとしてではなく文字列として渡されるため正しく動作しません。文字列として渡してスクリプトでリストに再度変換しようとしましたが、それも正しく動作しません。 Listをそのまま渡す方法はありますか?私は毎回2つのリストを持っています。親プロセス、サブプロセスコールで2つのリストを渡す方法があれば教えてください。 サンプルコード:サブコード呼び出しのpythonスクリプトで引数としてリストを渡す

subprocess.check_output(["python","Metadata_Index_EAV_LOAD.py",Dataset1,MetaDataIndex_Table,SchemaFields,FieldValues,r_date]) 

SchemaField、結果は私が引数として渡す必要がある二つのリストです。

+1

呼び出しているスクリプトはPythonファイルなので、それをインポートして直接関数を呼び出すのはなぜですか? –

+0

bqテーブルにデータを挿入するためのスクリプトは、チームによって広く使用できるように、独立している必要があります。私はそれを直接インポートする場合、それはハードコーディングのようなものであり、回避する必要があります。必要は:table_name、dataset、schemafileds(リスト)、値(値)を渡し、挿入されたレコードを取得します。希望、私は直接輸入を避ける理由を説明することができます。 – Shikha

+0

サンプルコードに 'list'という名前の変数はありません。他の変数の種類は何ですか?最終的に、 'subprocess'を使用すると、シェルを介して指定されたプログラムを呼び出すのと同じです(ほとんど)。あなたが 'Metadata_Index_EAV_LOAD.py'を直接実行していたら、どうしますか?その議論はどのように見えるでしょうか? 'subprocess'の呼び出しをそのように見せてください。 – jamesdlin

答えて

0

argsでリストを渡したいと思うかもしれませんが、そうしないでください。 なぜですか?カーネルに渡されるコマンドラインの長さには限界があるためです。最新のLinuxディストリビューションはかなり長い文字列を受け入れますが、まだまだです。特殊文字などを含むことができるものがたくさんあるとき、時にはひどく間違っていることがあります。特に、受信者のスクリプトを他の人に使用する場合は、シェルをバイパスしてスクリプトに直接データを送信することを忘れる可能性があります。そしてこの場合、全体の混乱が起きる可能性があります。

パイプを使用することをお勧めします。私。受信者はsys.stdinから読み込み、送信者はPopen()。communicate()を使用します。このような 何か:

# Receiver: 
from cPickle import loads 
import sys 

data = sys.stdin.read() # This will return after '^D' is received. 
data = loads(data) 
print "I received:" 
for x in data: 
    print x 
    print "\t", data[x] 

# Sender: 
from cPickle import dumps 
from subprocess import Popen, PIPE 

data = {"list1": [1, 2, 3, 4], 
    "list2": [3, 4, 5, 6]} 
cmd = ["python", "receiver.py"] 
p = Popen(cmd, stdin=PIPE, stdout=PIPE, stderr=PIPE) 
result, error = p.communicate(dumps(data)) 
if error: 
    raise Exception(error) 
print "Receiver sent:" 
print result 

、他の人が別の答えで示唆されているように、その後の酸洗が、JSONを使用していない、あなたのスクリプトにデータを送信するためにはPythonを使用しない必要がある場合。 それともあなたも)(literal_eval使用することができます。

# In receiver: 
from ast import literal_eval 
import sys 

data = sys.stdin.read() 
data = literal_eval(data) 
#... 

# And in sender: 
# ... 
result, error = p.communicate(repr(data)) 
#... 

literal_eval()で評価するのevalの安全なバージョンを()のみ組み込みデータ型ではなく、表情やその他のオブジェクト。それでも引数を使用して主張する場合

、あなたのようなものを使用する必要があります

list1 = [1, 2, 3, 4] 

def convert (l): 
    return ",".join((str(x) for x in l)) 

def get (s): 
    return s.split(",") 

をしかし、その後、あなたはあなたのセパレータは、文字列のどこにも表示されていないことを確認する必要がありますまたはエスケープ機構を作ります。また、英数字のみを送信しない場合は、OSおよび/またはシェルとの衝突を避けるために、URLセーフBase64を使用してコードをエンコードする必要があります。

+0

ありがとうございます。それは理解するのがはっきりしています。私のリストには特別な文字などが含まれています...それはもっと完璧な方法だと思われます。試してみて、それがどのように更新されるでしょう。 – Shikha

+0

私はパイプを使用し、私の必要性に応じて動作します。華麗な解決に感謝します。 – Shikha

0

あなたはあなただけのショートカットを再使用してリストにidを追加するには、コマンドライン引数に

parser = argparse.ArgumentParser() 
parser.add_argument('-sf','--schema_field', action='append', help="List of id's") 
args = parser.parse_args() 

この方法を使用して入力引数を処理するために、あなたのmainScriptにargparse設定できます。

python -c mainScript.py -sf 1001 -sf 1002 -sf 1003 

これで、メインスクリプト内のリストとしてargs.schema_fieldが返されます。複雑なオプションと位置コマンドライン引数を処理

は間違いなくargparseのための仕事である - ので、私はここに公式ドキュメントの上に行くお勧めします:https://docs.python.org/2/howto/argparse.html

0

あなたはおそらく、このような提案in this answerとしてリストとして引数を渡す方法を見つけることができるが、まだ簡単な解決方法は、json.loadsメソッドを使用することです。

import json 
schema_list = json.loads(SchemaFields) 
values = json.loads(FieldValues) 

そして、あなたはおそらく文字列として引数を送信し続ける必要があります:

代わりのインスタンスに対してlist(SchemaFields)を実行するには、のようなものを実行してみてください。

まだローズマンのコメントに同意します。これらの操作をすべて準備した基本クラスを使用してメインスクリプトから呼び出すだけであれば、これははるかに単純になります。あなたはメインスクリプトのsys.args入力を送ることができるので、この方法で値をコーディングしてください)。

関連する問題