Alle Variablen in einem Programm von [hier Ihre Lieblingssprache] auflisten oder auflisten [geschlossen]

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

Frage

Ein Freund hat mich letzte Woche gefragt, wie man alle Variablen innerhalb eines Programms/einer Funktion usw. aufzählt oder auflistet.zum Zwecke des Debuggens (im Wesentlichen eine Momentaufnahme von allem erstellen, damit Sie sehen können, auf welche Variablen gesetzt ist oder ob sie überhaupt gesetzt sind).Ich habe mich ein wenig umgesehen und einen relativ guten Weg für Python gefunden:

#!/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

was etwa Folgendes ausgeben wird:

__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

Ich habe bisher einen teilweisen Weg in PHP gefunden (mit freundlicher Genehmigung von Link Text), aber es werden nur alle Variablen und ihre Typen aufgelistet, nicht der Inhalt:

<?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 />';
        }
?>

Also habe ich es dir gesagt:Wie listen Sie alle Variablen und deren Inhalte in Ihrer Lieblingssprache auf?


Bearbeitet von VonC:Ich schlage vor, dass diese Frage dem Geist eines kleinen „Code-Herausforderung".
Wenn Sie damit nicht einverstanden sind, bearbeiten und entfernen Sie einfach das Tag und den Link.

War es hilfreich?

Lösung

In Python, Einheimischen verwendet, die ein Wörterbuch gibt alle lokalen Bindungen enthält, so eval vermeiden:

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

Andere Tipps

Dies ist, was es aussehen würde wie in Rubin :

#!/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

die folgende Ausgabe

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"

Allerdings haben Sie nicht die Art von Objekt zur Ausgabe der Variablenreferenzen anstelle des Typs bedeuten, verwendet, um die variable Kennung darstellen? IOW, sollte die Art von foo3 Hash (oder dict) statt String, nicht wahr? In diesem Fall wäre der Code

#!/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

und das Ergebnis ist

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"

In PHP Sie könnten dies tun:

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

In Lua ist die grundlegende Datenstruktur die Tisch und sogar die globale Umgebung _G ist eine Tabelle.Eine einfache Aufzählung reicht also aus.

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

IPython:

whos

Sie könnten empfehlen auch Spyder an Ihren Freund, die so ziemlich diese Variablen zeigt wie Matlab tut und bietet eine grafische Oberfläche für Zeile-für-Zeile-Debugging.

Bash:

set

Disclaimer: Nicht meine Lieblingssprache

Ein voll rekursive PHP Einzeiler:

print_r(get_defined_vars());

Als erstes würde ich einfach einen Debugger ;-p verwenden Visual Studio, zum Beispiel hat „Locals“ und „Watch“ Fenster, die alle Variablen zeigen usw. Sie wollen, voll erweiterbar auf jeder Ebene.

In C # kann man wirklich nicht bei Methode Variablen bekommt sehr leicht (und sie viele gut durch den Compiler entfernt werden) - aber Sie können Felder etc über Reflexion zugreifen:

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

Perl. Behandelt nicht my Einheimische, und filtert nicht einige nutzlose Referenzen, aber alles in Paketbereich zu sehen.

my %env = %{__PACKAGE__ . '::'};
while (($a, $b) = each %env) {
    print "\$$a = $$b\n";
    print "\@$a = (@$b)\n";
    print "%$a = (@{[%$b]})\n";
    print "*$a = $b\n";
}

In Java würde das Problem zu C # ähnlich sein, nur in einem ausführlichen Modus (ich weiß, ICH WEIß ;) Java ist die ausführliche ... Sie deutlich gemacht bereits;) )

Sie können auf Felder durch Refection einzuwenden, aber Sie können nicht ohne weiteres auf Verfahren lokale Variablen zugreifen. So ist die folgende nicht für die statischen Analyse-Code, aber für die Runtime-Debugging nur.

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

In der R Sprache

ls()

und alle Objekte aus dem Arbeitsspeicher entfernen

rm(list=ls(all=TRUE))

In REBOL, alle Variablen leben in einem Kontext vom Typ object!. Es gibt einen globalen Kontext, und jede Funktion hat ihren eigenen impliziten lokalen Kontext. Sie können explizit neue Kontexte erstellen, indem Sie einen neuen object! herbeizuführen (oder mit der context-Funktion). Dies unterscheidet sich von traditionellen Sprachen, da Variablen (genannt „Wörter“ in REBOL) einen Verweis auf ihren Kontext mit sich herumtragen, auch wenn sie den „Umfang“ verlassen haben, in dem sie definiert wurden.

So ist unter dem Strich, dass ein Zusammenhang gegeben, können wir die Variablen aufzulisten es definiert. Wir werden Ladislav Mecir des verwenden context-words? Funktion.

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

Jetzt können wir alle auflisten, die Worte im globalen Kontext definiert. (Es gibt ein Los von ihnen.)

probe context-words? system/words

Wir können auch eine Funktion schreiben, die dann die Variablen listet es definiert.

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

Was wir kann nicht so weit in REBOL, tun, was ich weiß, ist das Kontextbaum gehen, obwohl der Dolmetscher diese in der Lage sein scheint gut zu tun perfekt, wenn es wie beschließt zu binden Worte zu ihren Kontexten. Ich denke, das liegt daran, dass der Kontextbaum (das heißt, Umfang) eine „Form“ zu der Zeit kann ein Wort gebunden ist aber eine ganz andere, zu der Zeit ausgewertet wird.

quick and dirty JavaScript-Lösung wenn Sie Firebug installiert (oder einen anderen Browser mit console.log). Wenn Sie nicht tun, werden Sie console.log ändern müssen, um document.write und laufen in an als Inline-Skript am Ende Ihres. Ändern max_depth, wie viele Ebenen der Rekursion Sie wollen (Vorsicht!).

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

Common Lisp:

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

Um auch alle gebundenen Werte zeigen:

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

Dies ist eine lange Liste, und nicht besonders nützlich. Ich würde wirklich den integrierten Debugger verwenden.

Hier ist eine Idee für oo-Sprachen.

Als erstes müssen Sie so etwas wie toString () in Java sinnvollen Inhalt zu drucken. Zweitens - muss man sich auf ein Objekt-Hierarchie beschränken. Im Konstruktor des Root-Objekts (wie Alle in Eiffel), Ihr Register der Instanz bei der Erstellung in einer Art globaler Liste. Während zerstörung, deregistrieren Sie (sollten Sie einige Datenstruktur zu verwenden, die schnell insert / Suche / Entfernung erlaubt). Jedes Mal, während der Programmausführung, können Sie diese Datenstruktur zu Fuß durch und drucken Sie alle Objekte registriert es.

Aufgrund seiner Struktur, könnte Eiffel für diesen Zweck sehr gut sein. Andere Sprachen haben Probleme mit Objekten, die nicht vom Benutzer definiert sind (beispielsweise die jdk-Klassen). In Java könnte es möglich sein, eigene Objekt-Klasse mit einiger Open-Source-jdk zu erstellen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top