80

先週、友人が、プログラム/関数/その他内のすべての変数を列挙またはリストする方法を私に尋ねました。デバッグの目的で(基本的にすべてのスナップショットを取得して、どの変数が設定されているか、または設定されているかを確認できるようにします)。少し調べてみたところ、Python の比較的良い方法が見つかりました。

#!/usr/bin/python                                                                                                                                                                                                                           
foo1 = "こんにちは世界"
foo2 = "バー"
foo3 = {"1":"a",
        "2":"b"}
foo4 = "1+1"

dir() の名前:
    myvalue = eval(名前)
    出力名、「is」、type(name)、「and is equal to」、myvalue

次のような出力が得られます。

__builtins__ は <type 'str'> であり、<module '__builtin__' (組み込み)> と等しい
__doc__ は <type 'str'> であり、None に等しい
__file__ は <type 'str'> であり、./foo.py と等しい
__name__ は <type 'str'> であり、__main__ と等しい
foo1 は <type 'str'> であり、Hello world と同じです
foo2 は <type 'str'> であり、bar と等しい
foo3 は <type 'str'> であり、{'1': 'a', '2': 'b'} と等しい
foo4 は <type 'str'> であり、1+1 に等しい

これまでのところ、PHP で部分的な方法を見つけました ( link textの厚意による) が、内容ではなく、すべての変数とその型のみを一覧表示しています。

<?php
// いくつかの変数を作成します
$バー = 'フー';
$foo ='バー';
// 新しい配列オブジェクトを作成します
$arrayObj = new ArrayObject(get_defined_vars());
// 配列オブジェクトをループし、変数と値をエコー
for($iterator = $arrayObj->getIterator(); $iterator->valid(); $iterator->next())
        {
        echo $iterator->key() . ' => ' . $iterator->current() . '<br />';
        }
?>

すべての変数とその内容をお気に入りの言語で一覧表示するにはどうすればよいでしょうか?


VonCによる編集:この質問は、小さな「コードチャレンジ」の精神に従うことを提案します。
同意しない場合は、タグとリンクを編集して削除してください。

4

16 に答える 16

98

Python では、すべてのローカル バインディングを含む辞書を返す locals を使用して、eval を回避します。

>>> foo1 = "Hello world"
>>> foo2 = "bar"
>>> foo3 = {"1":"a",
...         "2":"b"}
>>> foo4 = "1+1"

>>> import pprint
>>> pprint.pprint(locals())
{'__builtins__': <module '__builtin__' (built-in)>,
 '__doc__': None,
 '__name__': '__main__',
 'foo1': 'Hello world',
 'foo2': 'bar',
 'foo3': {'1': 'a', '2': 'b'},
 'foo4': '1+1',
 'pprint': <module 'pprint' from '/usr/lib/python2.5/pprint.pyc'>}
于 2009-01-10T11:30:39.630 に答える
13

IPython:

whos

また、Matlab とほとんど同じようにこれらの変数を表示し、行ごとのデバッグ用の GUI を提供する Spyderを友人に勧めることもできます。

于 2013-06-06T21:29:37.410 に答える
11

Rubyでは次のようになります。

#!/usr/bin/env ruby

foo1 = 'Hello world'
foo2 = 'bar'
foo3 = { '1' => 'a', '2' => 'b' }
foo4 = '1+1'

b = binding
local_variables.each do |var|
  puts "#{var} is #{var.class} and is equal to #{b.local_variable_get(var).inspect}"
end

どちらが出力されますか

foo1 は文字列で、「Hello world」と同じです
foo2 は String であり、「bar」と等しい
foo3 は文字列であり、{"1"=>​​"a", "2"=>"b"} と等しい
foo4 は文字列で、「1+1」に等しい

しかし、変数の識別子を表すために使用される型ではなく、変数が参照するオブジェクトの型を出力するつもりではありませんでしたか? IOW、 の型はではなく(または)であるfoo3必要がありますよね? その場合、コードはHashdictString

#!/usr/bin/env ruby

foo1 = 'Hello world'
foo2 = 'bar'
foo3 = { '1' => 'a', '2' => 'b' }
foo4 = '1+1'

b = binding
local_variables.each do |var|
  val = b.local_variable_get(var)
  puts "#{var} is #{val.class} and is equal to #{val.inspect}"
end

結果は

foo1 は文字列で、「Hello world」と同じです
foo2 は String であり、「bar」と等しい
foo3 はハッシュであり、{"1"=>​​"a", "2"=>"b"} と等しい
foo4 は文字列で、「1+1」に等しい
于 2009-01-10T11:10:17.380 に答える
9

Lua では、基本的なデータ構造はテーブルであり、グローバル環境 _G もテーブルです。したがって、単純な列挙でうまくいきます。

for k,v in pairs(_G) do
  print(k..' is '..type(v)..' and is equal to '..tostring(v))
end
于 2009-05-23T18:28:11.923 に答える
9

PHPでは、これを行うことができます:

$defined = get_defined_vars(); 
foreach($defined as $varName => $varValue){
 echo "$varName is of type ".gettype($varValue)." and has value $varValue <br>";
}
于 2009-01-10T13:17:46.887 に答える
6

完全に再帰的な PHP ワンライナー:

print_r(get_defined_vars());
于 2009-05-26T11:24:21.777 に答える
6

バッシュ:

set

免責事項: 私の好きな言語ではありません!

于 2009-05-26T03:33:42.337 に答える
5

R言語で

ls()

作業メモリからすべてのオブジェクトを削除する

rm(list=ls(all=TRUE))
于 2013-03-06T20:28:52.623 に答える
4

Perl。ローカルを処理myせず、一部の不要な参照を除外しませんが、パッケージスコープ内のすべてを表示できます。

my %env = %{__PACKAGE__ . '::'};
while (($a, $b) = each %env) {
    print "\$$a = $$b\n";
    print "\@$a = (@$b)\n";
    print "%$a = (@{[%$b]})\n";
    print "*$a = $b\n";
}
于 2009-03-19T16:42:59.340 に答える
4

まず、デバッガーを使用するだけです。たとえば、Visual Studio には、必要なすべての変数などを表示する「ローカル」ウィンドウと「ウォッチ」ウィンドウがあり、任意のレベルに完全に拡張できます。

C# では、メソッド変数を簡単に取得することはできません (そして、それらの多くはコンパイラによって削除される可能性があります)。ただし、リフレクションを介してフィールドなどにアクセスできます。

static class Program { // formatted for minimal vertical space
    static object foo1 = "Hello world", foo2 = "bar",
                  foo3 = new[] { 1, 2, 3 }, foo4;
    static void Main() {
        foreach (var field in typeof(Program).GetFields(
                BindingFlags.Static | BindingFlags.NonPublic)) {
            var val = field.GetValue(null);
            if (val == null) {
                Console.WriteLine("{0} is null", field.Name);
            } else {
                Console.WriteLine("{0} ({1}) = {2}",
                    field.Name, val.GetType().Name, val);
            }
        }
    }
}
于 2009-01-10T10:03:01.820 に答える
4

マトラブ:

who
于 2009-05-23T18:49:02.870 に答える
2

Javaでは、問題はC#に似ていますが、より詳細なモードでのみです(私は知っています、は知っています;)Javaは詳細です...あなたはすでにそれを明確にしました;)

Refection を介してオブジェクト フィールドにアクセスできますが、メソッドのローカル変数には簡単にアクセスできない場合があります。したがって、以下は静的解析コードではなく、ランタイム デバッグのみを対象としています。

package test;

import java.lang.reflect.Field;
import java.security.AccessController;
import java.security.PrivilegedAction;

/**
 * 
 * @author <a href="https://stackoverflow.com/users/6309/vonc">VonC</a>
 */
public class DisplayVars
{

    private static int field1 = 1;
    private static String field2 = "~2~";
    private boolean isField = false;

    /**
     * @param args
     */
    public static void main(final String[] args)
    {
        final Field[] someFields = DisplayVars.class.getDeclaredFields();
        try
        {
            displayFields(someFields);
        } catch (IllegalAccessException e)
        {
            e.printStackTrace();
        }
    }

    /**
     * @param someFields
     * @throws IllegalAccessException
     * @throws IllegalArgumentException
     */
    @SuppressWarnings("unchecked")
    public static void displayFields(final Field[] someFields)
            throws IllegalAccessException
    {
        DisplayVars anObject = new DisplayVars();
        Object res = null;
        for (int ifields = 0; ifields < someFields.length; ifields++)
        {
            final Field aField = someFields[ifields];
            AccessController.doPrivileged(new PrivilegedAction() {
                public Object run()
                {
                    aField.setAccessible(true);
                    return null; // nothing to return
                }
            });
            res = aField.get(anObject);
            if (res != null)
            {
                System.out.println(aField.getName() + ": " + res.toString());
            } else
            {
                System.out.println(aField.getName() + ": null");
            }
        }
    }
}
于 2009-01-10T13:23:07.703 に答える
1

REBOL では、すべての変数は typeのコンテキストobject!内に存在します。グローバル コンテキストがあり、すべての関数には独自の暗黙的なローカル コンテキストがあります。object!新しいコンテキストを作成する(または関数を使用する)ことで、新しいコンテキストを明示的に作成できますcontext。変数 (REBOL では「単語」と呼ばれる) は、変数が定義された「スコープ」を離れた場合でも、コンテキストへの参照を保持するため、これは伝統的な言語とは異なります。

つまり、要するに、コンテキストが与えられれば、それが定義する変数をリストできるということです。Ladislav Mecir のcontext-words?関数を使用します。

context-words?: func [ ctx [object!] ] [ bind first ctx ctx ]

これで、グローバル コンテキストで定義されたすべての単語を一覧表示できます。(たくさんあります。)

probe context-words? system/words

関数が定義する変数をリストする関数を書くこともできます。

enumerable: func [a b c /local x y z] [
  probe context-words? bind? 'a
]

私が知る限り、REBOL でできないことは、コンテキスト ツリーをたどることです。ただし、インタプリタは、単語をコンテキストにバインドする方法を決定するときに、これを完全にうまく実行できるようです。これは、コンテキスト ツリー (つまり、スコープ) が、単語がバインドされた時点では 1 つの "形状" を持っていても、評価された時点ではまったく別の "形状" を持っている可能性があるためだと思います。

于 2009-05-26T08:54:01.410 に答える
1

FireBug がインストールされている場合 (または console.log を備えた別のブラウザー) の場合は、素早く汚い JavaScript ソリューションです。そうでない場合は、console.log を document.write に変更し、.log の最後でインライン スクリプトとして実行する必要があります。MAX_DEPTH を必要な再帰レベルの数に変更します (注意してください!)。

(function() {
    var MAX_DEPTH = 0;
    function printObj(name, o, depth) {
        console.log(name + " type: '"+typeof o+"' value: " + o);

        if(typeof o == "function" || depth >= MAX_DEPTH) return;
        for(var c in o) {
            printObj(name+"."+c, o[c], depth+1);
        }
    }
    for(var o in window) {
        printObj(o, window[o], 0);
    }
})();
于 2009-05-26T20:12:40.837 に答える
0

一般的な Lisp:

(do-all-symbols (x) (print x))

すべてのバインドされた値も表示するには:

(do-all-symbols (x) (print x) (when (boundp x) (print (symbol-value x))))

これは長いリストであり、特に有用ではありません。私は本当に統合デバッガーを使用します。

于 2009-05-23T18:55:52.810 に答える
0

これが oo-languages のアイデアです。

まず、意味のあるコンテンツを出力するために、Java で toString() のようなものが必要です。2 つ目 - オブジェクト階層を 1 つに制限する必要があります。ルートオブジェクト (Eiffel の Any など) のコンストラクターで、作成時にインスタンスをある種のグローバル リストに登録します。破棄中は、登録を解除します (高速な挿入/検索/削除が可能なデータ構造を必ず使用してください)。プログラムの実行中はいつでも、このデータ構造を調べて、そこに登録されているすべてのオブジェクトを出力できます。

その構造上、エッフェルはこの目的に非常に適しているかもしれません。他の言語では、ユーザー定義ではないオブジェクト (jdk クラスなど) に問題があります。Java では、オープンソースの jdk を使用して独自のオブジェクト クラスを作成できる場合があります。

于 2009-05-25T16:19:26.227 に答える