【发布时间】:2011-02-19 13:06:01
【问题描述】:
我知道如何使用以下代码打印“所有”全局变量
for k,v in pairs(_G) do
print("Global key", k, "value", v)
end
所以我的问题是如何对当前执行的函数可访问的所有变量执行此操作,这可以执行 locals() 为 Python 执行的操作。
【问题讨论】:
标签: lua introspection
我知道如何使用以下代码打印“所有”全局变量
for k,v in pairs(_G) do
print("Global key", k, "value", v)
end
所以我的问题是如何对当前执行的函数可访问的所有变量执行此操作,这可以执行 locals() 为 Python 执行的操作。
【问题讨论】:
标签: lua introspection
这是一个locals() 函数的实现。它将从调用范围返回一个本地表:
function locals()
local variables = {}
local idx = 1
while true do
local ln, lv = debug.getlocal(2, idx)
if ln ~= nil then
variables[ln] = lv
else
break
end
idx = 1 + idx
end
return variables
end
请注意,在 lua REPL 中,每一行都是具有单独局部变量的单独块。此外,还会返回内部变量(名称以 '(' 开头,如果要删除它们):
> local a = 2; for x, v in pairs(locals()) do print(x, v) end
a 2
(*temporary) function: 0x10359b38
感谢您的接受。你已经解开了最后一块拼图! ;-)
Upvalues 是来自外部作用域的局部变量,在当前函数中使用。他们既不在_G 也不在locals()
function upvalues()
local variables = {}
local idx = 1
local func = debug.getinfo(2, "f").func
while true do
local ln, lv = debug.getupvalue(func, idx)
if ln ~= nil then
variables[ln] = lv
else
break
end
idx = 1 + idx
end
return variables
end
示例(请注意,您必须使用 a 才能显示):
> local a= 2; function f() local b = a; for x,v in pairs(upvalues()) do print(x,v) end end; f()
a 2
【讨论】:
pairs存储在(*temporary)中?
使用debug.getlocal。
【讨论】:
local foobar = 1
local i = 0
repeat
local k, v = debug.getlocal(1, i)
if k then
print(k, v)
i = i + 1
end
until nil == k
输出:
foobar 1
i 2
【讨论】:
lua test.lua 执行。我错过了什么吗?
上面梅加登法官的循环版本的问题只是local i = 0。
它什么也不做,因为第一个索引为 '0' 的总是返回 nil。
记住 Lua 索引默认以“1”开头,而不是像 C/C++ 那样的“0”。 当然,您可以将“0”用于具有自己类型的索引,但默认功能 期待默认的 '1' 作为第一个索引。
只需将其更改为local i = 1,他的循环就可以正常工作了。
【讨论】:
您可以使用getfenv 获取本地环境。
getfenv ([f]) 返回当前 函数使用的环境。 F 可以是 Lua 函数或数字 指定该堆栈中的函数 级别:级别 1 是函数调用 得到芬夫。如果给定的函数不是 一个 Lua 函数,或者如果 f 为 0,getfenv 返回全局环境。这 f 的默认值为 1。
编辑:抱歉,我错了。
我刚刚检查了 Lua 源代码。 debug.getlocal() 是获取局部变量的唯一途径。
Lua 使用内部的Proto 结构,并且不允许我们访问它。
(Proto 包含本地属性和父 Proto 引用。使用 getfenv 迭代函数的 Proto,
我们还迭代继承的属性,而不是我们想要的)
用户可以使用环境和set/getfenv 函数或使用元表来定义他们的Proto。
【讨论】:
foobar: local foobar = 1; for k,v in pairs(getfenv()) do print(k, v) end 我错过了什么吗?
getfenv 只会显示具有给定范围/环境的全局变量。
debug.getlocal,否则我们无法真正获得本地声明。