تعداد أو قائمة جميع المتغيرات في برنامج [اللغة المفضلة لديك هنا] [مغلقة]
-
08-07-2019 - |
سؤال
سألت صديقا لي في الأسبوع الماضي كيف أن تعداد أو قائمة جميع المتغيرات داخل البرنامج/وظيفة/.... الخلأغراض التصحيح (أساسا الحصول على لقطة من كل شيء حتى تتمكن من رؤية ما المتغيرات يتم تعيين إلى ، أو إذا تم تعيين على الإطلاق).بحثت قليلا ووجدت جيدة نسبيا الطريق بايثون:
#!/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.