2017-01-09 10 views
0

これは私の辞書です:辞書からグローバル変数を割り当てる方法は?

vimvar = {'startline' : [ 'startline' , 'int(vim.eval("s:StartLine"))' ], 
      'startline-1' : [ 'startline' , 'int(vim.eval("s:StartLine"))-1'], 
      'endline'  : [ 'endline' , 'int(vim.eval("s:EndLine"))' ], 
      'gcase'  : [ 'gCASE'  , 'vim.eval("g:CASE")'   ], 
      'akeyw'  : [ 'akeyw'  , 'vim.eval("a:keyw")'   ] 
     } 

これは私のチェックリストです:私は何をしたいか

importlist = ['startline', 'gcase', 'akeyw'] 

importlistの値がvimvar辞書にキーとして存在しているかどうかを確認することです。

よりもはいている場合:

  1. (キーに関連付けられている)サブリストにおける第一のフィールドの値は、新しいグローバル変数でなければなりません。

  2. (キーに関連付けられた)サブリストの2番目のフィールドの値を実行する必要があります。テキストエディタvimから変数をインポートします。

私が上に実現するために、このコードを作成しました:

for n in importlist: 
    for key,val in vimvar.items(): 
     if n in vimvar: 
     exec('global ' + vimvar[key][0]) 
     exec(vimvar[val][0] + '=vimvar[val][1]') 

しかし、それはエラーに私が間違っていた何

undefined variable 'sa'

undefined variable 'gCASE', unhashable type list

など

を与えるものは何でも私は?

+0

エラーメッセージにエラーの行がありますか? – nbro

+2

あなたが間違ったのは、グローバル値に 'exec'を割り当てることです。あなたはそれをするために_incredibly_良い理由がありますか? – TigerhawkT3

+1

大きな問題点:問題は、ループに1つのループが多すぎるということです。 'N'が辞書にあるかどうかをチェックして、あなたはimportlistにnの をDEFにつながる_current_辞書の繰り返し、使用:nの場合vimvarで を: のexec(「グローバル」+ vimvar [N] [0]) exec( '='。join(vimvar [n])) –

答えて

2

2つの問題:あなたは一度だけループする必要がある場合

まず、あなたは、二回ループしています。(あなた本当にはグローバル変数であることを、それを必要に応じて)

data = {} 
for n in importlist: 
    if n in vimvar: 
    name, val = vimvar[n] 
    data[name] = exec(val) 

またはglobals()辞書を変更します:

for n in importlist: 
    if n in vimvar: 
    name, val = vimvar[n] 
    globals()[name] = exec(val) 

あなたが、しようとすることができた場合は、コンテナオブジェクト(推奨)に割り当てるのいずれかグローバル変数に格納しないでください。信頼できる文字列にのみexec()を使用してください。なぜこのコードがあなたのソースに存在できないのでしょうか?例えば

vimvar = { 
    'startline': ['startline', int(vim.eval("s:StartLine"))], 
    'startline-1': ['startline', int(vim.eval("s:StartLine"))-1], 
    'endline': ['endline', int(vim.eval("s:EndLine"))], 
    'gcase': ['gCASE', vim.eval("g:CASE")], 
    'akeyw': ['akeyw', vim.eval("a:keyw")] 
} 

for n in importlist: 
    if n in vimvar: 
    name, val = vimvar[n] 
    globals()[name] = val 
+0

ありがとうございます。はい、他の(非Pythonの)スクリプトで必要とするので、グローバルを必要とします。私のスクリプトではうまくいかないようです)は、サブリストの最初の値を「キー」とし、サブリストの2番目の値を「val」とします。グローバルは最初の値でなければなりませんサブリストの2番目の値は次のように実行する必要があります... 'global gCASE'と' gCASE = vim.eval( "g:CASE") ' – Reman

+0

あなたはどんなエラーを出していますか? 'vim.eval()'ステートメントが正常であると仮定すると、コードは必要に応じて機能するはずです。 –

+0

(わかりやすくするために編集しましたが、 'key'という単語が混乱している可能性があります)。 Pythonコンソールでグローバル変数を設定すると、これを実際に見ることができます: 'globals()['gCASE'] = 1234' –

1

問題はライン

exec(vimvar[val][0] + '=vimvar[val][1]') 

である私は、あなたが辞書をインデックス化について混乱していると思う:あなたは、インデックスとしてヴァルを使用することを試みたが、それは単に意味がありません。例えば、あなたの参照の一つは次のように拡張されます

vimvar[['akeyw', 'vim.eval("a:keyw")']] 

まず、あなたは辞書のキーとしてリストを使用することはできません - それは「非ハッシュ」の問題があるものです。第二に、そのような要素は辞書のキーにありません。

おそらくval [0]としたらいいですか?あなたが面白いものをやっているので、私はあなたが達成したいとは思っていません。 として既にTigerHawkが指摘されているので、このようにグローバルに割り当てるのは一般的に悪い習慣です。

for n in importlist: 
    if n in vimvar: 
    name, val = vimvar[n] 
    ... 

第二に、あなたが割り当てにexec()を使用する必要はありません。

+0

Tnxプルーン:私が望むのは、上記の 'global gCASE'と' 'gCASE''で実行したいのですが、あなたが解決した問題よりももっと多くのことを学ぶでしょう。 'gCASE = vim.eval(" g:CASE ")' etc – Reman

2

ここで多くの問題

  • あなただけvim.evalコマンドへの呼び出しを実行するときexecglobalを使用して値
  • をdesyncing辞書であまり一つのループがあります。

私がドロップされるすべてのことexecものと再やるvimの評価エンジン:辞書は今だけvimのコマンドのパラメータが含まれていることを

vimvar = {'startline' : [ 'startline' , "s:StartLine" , 0], 
      'startline-1' : [ 'startline' , 's:StartLine' , -1 ], 
      'endline'  : [ 'endline' , "s:EndLine" , 0 ], 
      'gcase'  : [ 'gCASE'  , "g:CASE" ], 
      'akeyw'  : [ 'akeyw'  , "a:keyw" ] 
     } 

importlist = ['startline', 'gcase', 'akeyw'] 

results = dict() 

for n in importlist: 
    if n in vimvar: # key found in dict (no need for inner loop) 
    data = vimvar[n] # get value list 
    varname = data[0] # dict key name 
    command = data[1] # vim command to call 
    # call vim command 
    result = vim.eval(command) 

    if len(data)>2: 
     # perform optional conversion/offset, could work for string too 
     to_add = data[2] 
     result = type(to_add)(result) + to_add 

    # create dictionary entry 
    results[varname] = result 

print(results) 

注意を。変換/追加が必要な場合は、値リストに追加のパラメータがあります。 0の場合、結果は整数に変換され、-1の場合は変換され、1の場合は減算されます。それはあなたのすべてのコマンドをカバーすることは確かではありませんが、確かにいくつかのアイデアを提供

その後、データが変数に保存されているが、変数の辞書にされていません。例:

{'akeyw': 'something', 'gCASE': 'other', 'startline': 10} 

あなたは非常に簡単にアクセスすることができ、そしてそれは悪いコーディングの練習を必要としません。

+0

Jean-François、グローバルを避けるためにあなたのような辞書を作成しましたが、どのように辞書を返すのですか? return 'dictionary name'が機能しません:エラー: 'dictionary name'が定義されていません。 – Reman

+0

は 'results'を返します。これが辞書です。 –

+0

あなたは '返品'を意味しないのですか? – Reman

1

globalまたは'global'またはexecなしでこれを行う方法は次のとおりです。

グローバル変数が絶対に必要で、戻り値(関数が呼び出し元に値を提供する通常の方法)を保存できない場合は、辞書などの可変オブジェクトを使用します(How do I create a variable number of variables?を参照) 。

第2に、グローバル変数に割り当てる値(今では単純に変更できる辞書)は、=に追加する文字列ではなく、通常の式で、execで実行できます。 vimvarディクショナリの値は、目的の「変数名」(現在のキー)、使用する関数、および最終的なオフセットになります。

my_global_dict = {} 

def f(): 
    vimvar = {'startline' : ["s:StartLine", (vim.eval, int), 0], 
      'startline-1' : ["s:StartLine", (vim.eval, int), -1], 
      'endline'  : ["s:EndLine", (vim.eval, int), 0], 
      'gcase'  : ["g:CASE", (vim.eval,), 0], 
      'akeyw'  : ["a:keyw", (vim.eval,), 0] 
     } 
    importlist = ['startline', 'gcase', 'akeyw'] 
    for k in importlist: 
     if k in vimvar: 
      s,funcs,offset = vimvar[k] 
      for func in funcs: 
       s = func(s) 
      if offset: 
       s += offset 
      my_global_dict[k] = s 
関連する問題