2016-09-19 9 views
5

他の記事の後に、その名前に基づいて変数に関する情報を出力する関数があります。私はそれをモジュールに移動したいと思います。変数をモジュール内の文字列として扱う

#python 2.7 
import numpy as np 
def oshape(name): 
    #output the name, type and shape/length of the input variable(s) 
    #for array or list 
    x=globals()[name] 
    if type(x) is np.array or type(x) is np.ndarray: 
     print('{:20} {:25} {}'.format(name, repr(type(x)), x.shape)) 
    elif type(x) is list: 
     print('{:20} {:25} {}'.format(name, repr(type(x)), len(x))) 
    else: 
     print('{:20} {:25} X'.format(name, type(t))) 

a=np.array([1,2,3]) 
b=[4,5,6] 
oshape('a') 
oshape('b') 

出力:私はそれを再利用できるようにモジュールに()この関数oshapeを入れたい

a     <type 'numpy.ndarray'> (3,) 
b     <type 'list'>    3 

。ただし、モジュールを配置すると、メインモジュールからグローバルにアクセスすることはできません。私は 'import __main__'のようなものを試し、関数globals()を格納してそれをサブモジュールに渡すことさえしました。問題は、globals()が、呼び出されたモジュールのグローバルを返す関数であり、モジュールごとに異なる関数ではないということです。

import numpy as np 
import olib 

a=np.array([1,2,3]) 
b=[4,5,6] 

olib.oshape('a') 
olib.oshape('b') 

は私を与える:

KeyError: 'a' 

追加情報: 目標は、冗長なタイピングを減らすことです。わずかな変更では、oshapeは、変数のリストを報告する可能性が(私はそれが質問のために簡単にするためにそれを取った)ので、私はそれが好きで使用することができますで変数名を入力する必要

ので
oshape('a', 'b', 'other_variables_i_care_about') 

ソリューションを2倍は私が探しているものではありません。また、変数を渡すだけでは、名前を印刷することはできません。長いログファイルでこれを使用して、計算の結果を表示することを考えてください。&可変サイズをチェックしてください。

+1

は、理由だけではなく、配列を渡していませんか? –

+0

なぜ変数を直接渡してそのまま使うのですか? – njzk2

+0

変数の名前を出力したいからです。私は print( 'a'、タイプ(a)、a.shape)のようなことをしていました。 しかし、それは面倒です。 – SolverWorld

答えて

1

あなたのロジックは複雑ですが、あなたはすでに変数名を文字列として渡しているので、配列自体を渡すだけでアクセスできないものを探しているわけではありません。

import numpy as np 
import olib 

a = np.array([1, 2, 3]) 
b = [4, 5, 6] 
olib.a = a 
olib.b = b 
olib.oshape('a') 
olib.oshape('b') 

これは、任意の引数を取り、コードがATTRS用から実行されるモジュールを検索します:

import numpy as np 
import sys 
from os.path import basename 
import imp 

def oshape(*args): 
    # output the name, type and shape/length of the input variable(s) 
    # for array or list 
    file_name = sys.argv[0] 
    mod = basename(file_name).split(".")[0] 
    if mod not in sys.modules: 
     mod = imp.load_source(mod, file_name) 
     for name in args: 
      x = getattr(mod, name) 
      if type(x) is np.array or type(x) is np.ndarray: 
       print('{:20} {:25} {}'.format(name, repr(type(x)), x.shape)) 
      elif type(x) is list: 
       print('{:20} {:25} {}'.format(name, repr(type(x)), len(x))) 
      else: 
       print('{} {} X'.format(name, type(x))) 
をあなたは正確にあなたのコードの作品を​​作りたいと思った場合しかし、あなたはモジュールのattibuteを設定することができているよう

ただ、変数名の文字列を渡す:

:~/$ cat t2.py 
import numpy as np 
from olib import oshape 

a = np.array([1, 2, 3]) 
b = [4, 5, 6] 
c = "a str" 

oshape("a", "b", "c") 


:$ python t2.py 
a     <type 'numpy.ndarray'> (3,) 
b     <type 'list'>    3 
c <type 'str'> X 
+0

これは、印刷したい各変数の冗長コードです。興味深い考え。 olib.globals = globals()を1回実行してモジュールからアクセスすることはできましたが、その呼び出しの後に新しい変数を作成することはできませんでした。 – SolverWorld

+0

関数またはラップされたolibで実行した場合、プロセスを自動化する方法があります。 –

+0

それは素晴らしい、あなたは簡単な例を与えることができますか?メインにコードを追加する必要がある場合は、モジュールを使用する目的を無効にし、元の質問に投稿したコードを使用することもできます。 – SolverWorld

2

実際の問題は、名前空間の問題です。

あなたはあなたの方法この方法で記述することができます。

def oshape(name, x): 
    # output the name, type and shape/length of the input variable(s) 
    # for array or list 
    if type(x) in (np.array, np.ndarray): 
     print('{:20} {:25} {}'.format(name, repr(type(x)), x.shape)) 
    elif type(x) is list: 
     print('{:20} {:25} {}'.format(name, repr(type(x)), len(x))) 
    else: 
     print('{:20} {:25} X'.format(name, type(x))) 

をし、このようにそれを使用します。

import numpy as np 
import olib 

a=np.array([1,2,3]) 
b=[4,5,6] 

olib.oshape('a', a) 
olib.oshape('b', b) 

が、引数内の変数とその名前を持っていることは非常に冗長に見えます。

もう1つの解決策は、globals()にメソッドを指定し、コードを保持することです。

モジュールによるグローバル変数の可視性については、this answerをご覧ください。

+0

あなたが言うように、最初の解決策は重複した入力です。そして、私はちょっとした修正を加えてoshape( 'a'、 'b'、 'other_vars_i_care_about')のようなことを言いたい。 2番目のソリューションにも同じ問題があります。つまり、各呼び出しでglobals()を渡すための冗長な型付けです。これは、Cスタイルのマクロが便利な場所です。 – SolverWorld

関連する問題