[여기서 가장 좋아하는 언어] 프로그램의 모든 변수를 열거하거나 나열하세요. [닫기]

StackOverflow https://stackoverflow.com/questions/430811

문제

지난주에 한 친구가 나에게 프로그램/함수/등 내의 모든 변수를 열거하거나 나열하는 방법을 물었습니다.디버깅 목적으로(기본적으로 어떤 변수가 설정되어 있는지 또는 설정되어 있는지 확인할 수 있도록 모든 것의 스냅샷을 가져오는 것)나는 조금 둘러보았고 Python에 대한 비교적 좋은 방법을 찾았습니다.

#!/usr/bin/python                                                                                                                                                                                                                           
foo1 = "Hello world"
foo2 = "bar"
foo3 = {"1":"a",
        "2":"b"}
foo4 = "1+1"

for name in dir():
    myvalue = eval(name)
    print name, "is", type(name), "and is equal to ", myvalue

그러면 다음과 같은 결과가 출력됩니다:

__builtins__ is <type 'str'> and is equal to  <module '__builtin__' (built-in)>
__doc__ is <type 'str'> and is equal to  None
__file__ is <type 'str'> and is equal to  ./foo.py
__name__ is <type 'str'> and is equal to  __main__
foo1 is <type 'str'> and is equal to  Hello world
foo2 is <type 'str'> and is equal to  bar
foo3 is <type 'str'> and is equal to  {'1': 'a', '2': 'b'}
foo4 is <type 'str'> and is equal to  1+1

나는 지금까지 PHP에서 부분적인 방법을 찾았습니다. 링크 텍스트) 그러나 모든 변수와 해당 유형만 나열되며 내용은 나열되지 않습니다.

<?php
// create a few variables
$bar = 'foo';
$foo ='bar';
// create a new array object
$arrayObj = new ArrayObject(get_defined_vars());
// loop over the array object and echo variables and values
for($iterator = $arrayObj->getIterator(); $iterator->valid(); $iterator->next())
        {
        echo $iterator->key() . ' => ' . $iterator->current() . '<br />';
        }
?>

그래서 나는 당신에게 다음과 같이 말했습니다.좋아하는 언어로 모든 변수와 그 내용을 어떻게 나열합니까?


편집자 VonC:나는 이 질문이 약간의 정신을 따를 것을 제안합니다.코드 챌린지".
동의하지 않으시면 태그와 링크를 수정하고 삭제하시면 됩니다.

도움이 되었습니까?

해결책

파이썬에서, 모든 로컬 바인딩을 포함하는 사전을 반환하는 지역 주민을 사용하여 평가를 피하십시오.

>>> 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'>}

다른 팁

이것이 모양의 모습입니다 루비:

#!/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 is String and is equal to "Hello world"
foo2 is String and is equal to "bar"
foo3 is String and is equal to {"1"=>"a", "2"=>"b"}
foo4 is String and is equal to "1+1"

그러나 변수 식별자를 나타내는 데 사용되는 유형 대신 변수 참조를 객체 유형을 출력하는 것을 의미하지 않습니까? iow, 유형 foo3 해야한다 Hash (또는 dict) 대신에 String, 오른쪽? 이 경우 코드가 될 것입니다

#!/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 is String and is equal to "Hello world"
foo2 is String and is equal to "bar"
foo3 is Hash and is equal to {"1"=>"a", "2"=>"b"}
foo4 is String and is equal to "1+1"

PHP에서는 다음을 수행 할 수 있습니다.

$defined = get_defined_vars(); 
foreach($defined as $varName => $varValue){
 echo "$varName is of type ".gettype($varValue)." and has value $varValue <br>";
}

LUA에서 기본 데이터 구조는 다음과 같습니다 테이블 그리고 지구 환경조차도 _g는 테이블입니다. 따라서 간단한 열거는 트릭을 수행합니다.

for k,v in pairs(_G) do
  print(k..' is '..type(v)..' and is equal to '..tostring(v))
end

Ipython :

whos

당신은 또한 추천 할 수 있습니다 스파이더 Matlab과 거의 비슷한 변수를 보여주는 친구에게 라인 별 디버깅을위한 GUI를 제공합니다.

세게 때리다:

set

면책 조항 : 내가 가장 좋아하는 언어가 아닙니다!

완전 재귀 PHP 원 라이너 :

print_r(get_defined_vars());

먼저, 예를 들어, 디버거; P Visual Studio를 사용하여 원하는 모든 변수 등을 표시하는 "현지인"및 "Watch"Windows가 있는데, 모든 수준으로 완전히 확장 할 수 있습니다.

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);
            }
        }
    }
}

Matlab :

who

펄. 처리하지 않습니다 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";
}

Java에서 문제는 C#과 유사하며 더 장황한 모드에서만 유사합니다 (알고 있습니다. 알아 ;) Java는 장방입니다 ... 당신은 이미 그것을 명확하게했습니다;) )

회피를 통해 객체 필드에 액세스 할 수 있지만 방법 로컬 변수에 쉽게 액세스 할 수 없습니다. 따라서 다음은 정적 분석 코드가 아니라 런타임 디버깅 전용입니다.

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");
            }
        }
    }
}

R 언어로

ls()

작업 메모리에서 모든 객체를 제거합니다

rm(list=ls(all=TRUE))

REBOL에서는 모든 변수가 문맥 유형의 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에서 하는 일은 컨텍스트 트리를 따라 올라가는 것이지만, 통역사는 단어를 컨텍스트에 바인딩하는 방법을 결정할 때 이 작업을 완벽하게 잘 수행할 수 있는 것 같습니다.나는 이것이 컨텍스트 트리(즉, 범위)가 단어가 바인딩될 때 하나의 "모양"을 가질 수 있지만 평가될 때 완전히 다른 "모양"을 가질 수 있기 때문이라고 생각합니다.

Firebug가 설치된 경우 빠르고 더러운 JavaScript 솔루션 (또는 Console.Log가있는 다른 브라우저). 그렇지 않은 경우 Console.log를 변경하여 Document.Write를 변경하고 끝에서 인라인 스크립트로 실행해야합니다. 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);
    }
})();

일반적인 LISP :

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

또한 모든 경계 값을 표시하려면 다음과 같습니다.

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

이것은 긴 목록이며 특히 유용하지 않습니다. 통합 디버거를 정말로 사용하겠습니다.

다음은 oo-languages에 대한 아이디어입니다.

먼저 의미있는 내용을 인쇄하려면 Java의 Tostring ()과 같은 것이 필요합니다. 둘째 - 하나의 객체 계층으로 자신을 제한해야합니다. root-bobject의 생성자 (Eiffel과 같은)에서, 당신의 당신은 어떤 종류의 글로벌 목록에서 생성시 인스턴스를 등록합니다. 파괴 중에는 데드 레저를 표시합니다 (빠른 삽입 / 검색 / 제거를 허용하는 일부 데이터 구조를 사용해야합니다). 프로그램 실행 중 언제든지이 데이터 구조를 걸어 가면서 등록 된 모든 객체를 인쇄 할 수 있습니다.

구조로 인해 에펠은이 목적에 매우 좋을 수 있습니다. 다른 언어는 사용자 정의되지 않은 객체 (예 : JDK 클래스)에 문제가 있습니다. Java에서는 Open-Source JDK를 사용하여 나만의 객체 클래스를 만들 수 있습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top