تعداد أو قائمة جميع المتغيرات في برنامج [اللغة المفضلة لديك هنا] [مغلقة]

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

سؤال

سألت صديقا لي في الأسبوع الماضي كيف أن تعداد أو قائمة جميع المتغيرات داخل البرنامج/وظيفة/.... الخلأغراض التصحيح (أساسا الحصول على لقطة من كل شيء حتى تتمكن من رؤية ما المتغيرات يتم تعيين إلى ، أو إذا تم تعيين على الإطلاق).بحثت قليلا ووجدت جيدة نسبيا الطريق بايثون:

#!/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:أقترح هذا السؤال يتبع روح قليلا "رمز التحدي".
إذا كنت لا توافق ، فقط تحرير وإزالة علامة الارتباط.

هل كانت مفيدة؟

المحلول

في بيثون ، باستخدام المحليين والتي ترجع قاموس يحتوي على جميع الارتباطات المحلية ، وبالتالي تجنب 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'>}

نصائح أخرى

هذا ما سيبدو في روبي:

#!/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>";
}

في لوا البيانات الأساسية الهيكل الجدول وحتى البيئة العالمية _G هو الجدول.لذا بسيط التعداد سوف تفعل خدعة.

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

IPython:

whos

يمكن أن نوصي أيضا سبايدر صديقك الذي يظهر هذه المتغيرات الى حد كبير مثل Matlab لا يوفر واجهة المستخدم الرسومية على خط سطرا التصحيح.

باش:

set

تنويه:غير المفضلة اللغة!

تماما العودية PHP بطانة واحدة:

print_r(get_defined_vars());

أولا, كنت ببساطة استخدام مصحح ;-p 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);
            }
        }
    }
}

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

في جافا المشكلة سوف تكون مشابهة C# في الوضع المطول (وأنا أعلم ، أعلم ;) جافا مطول... و قد أوضحت بالفعل؛) )

يمكنك الوصول إلى حقول كائن من خلال جبة خفيفة ، ولكن لا يجوز لك الوصول بسهولة إلى طريقة المتغيرات المحلية.لذا التالية ليست ثابتة تحليل التعليمات البرمجية ، ولكن وقت التصحيح فقط.

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) تحمل إشارة إلى سياقها في جميع أنحاء معهم ، حتى عندما تركت "نطاق" التي تم تعريفها.

إذن خلاصة القول هي أنه بالنظر إلى السياق ، يمكننا قائمة المتغيرات يعرف.سنستخدم لاديسلاف 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, بقدر ما أعرف, هو المشي سياق شجرة, على الرغم من أن المترجم يبدو أن تكون قادرة على القيام بذلك تماما عندما يقرر كيفية ربط الكلمات وسياقاتها.أعتقد أن هذا هو لأن سياق شجرة (أي نطاق) قد يكون أحد "الشكل" في ذلك الوقت كلمة لا بد ولكن آخر تماما في تقييمها.

سريعة وقذرة جافا سكريبت الحل إذا كان لديك الحرائق تثبيت (أو متصفح آخر مع وحدة التحكم.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);
    }
})();

Common Lisp:

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

أيضا عرض جميع بد القيم:

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

هذه هي قائمة طويلة و غير مفيدة.أنا حقا استخدام المصحح المتكاملة.

هنا هو فكرة oo-لغات.

أولا أنت بحاجة إلى شيء مثل toString() في جاوة طباعة ذات مغزى المحتويات.ثانيا - يجب أن تقيد نفسك كائن واحد-التسلسل الهرمي.في منشئ من الجذر-كائن (مثل أي في متحف اللوفر), السجل الخاص بك على سبيل المثال عند الخلق في نوع من القائمة العالمية.خلال التدمير عليك التسجيل (تأكد من استخدام بعض البيانات الهيكل الذي يسمح بسرعة إدراج / بحث / إزالة).في أي وقت أثناء تنفيذ البرنامج ، يمكنك المشي من خلال هذه البيانات هيكل و طباعة جميع الكائنات مسجلة هناك.

بسبب انها هيكل إيفل قد تكون جيدة جدا لهذا الغرض.لغات أخرى لديها مشاكل مع الكائنات التي لا المعرفة من قبل المستخدم (مثلjdk-فئات).في جافا فإنه قد يكون من الممكن إنشاء الخاصة بك كائن من الدرجة استخدام بعض المفتوحة المصدر jdk.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top