lua中的setfenv和getfenv

转载 2017年01月03日 23:05:20

设置函数环境——setfenv

  当我们在全局环境中定义变量时经常会有命名冲突,尤其是在使用一些库的时候,变量声明可能会发生覆盖,这时候就需要一个非全局的环境来解决这问题。setfenv函数可以满足我们的需求。

  setfenv(f, table):设置一个函数的环境

  (1)当第一个参数为一个函数时,表示设置该函数的环境

  (2)当第一个参数为一个数字时,为1代表当前函数,2代表调用自己的函数,3代表调用自己的函数的函数,以此类推

  所谓函数的环境,其实一个环境就是一个表,该函数被限定为只能访问该表中的域,或在函数体内自己定义的变量。下面这个例子,设定当前函数的环境为一个空表,那么在设定执行以后,来自全局的print函数将不可见,所以调用会失败。

-- 一个环境就是一个表,该表记录了新环境能够访问的全部域
newfenv = {}
setfenv(1, newfenv)
print(1)        -- attempt to call global `print' (a nil value)

  我们可以这样继承已有的域:

a = 10
newfenv = {_G = _G}
setfenv(1, newfenv)
_G.print(1)        -- 1
_G.print(_G.a)        -- 10
_G.print(a)        -- nil 注意此处是nil,新环境没有a域,但可以通过_G.a访问_G的a域

  可以看到,新环境中可以访问_G,但有一点就是_G中的所有函数必须手动调用,这样其实很不方便。我们可以使用metatable来对上述代码进行改进:

-- 任何赋值操作都对新表进行,不用担心误操作修改了全局变量表。另外,你仍然可以通过_G修改全局变量:
newfenv = {}
setmetatable(newfenv, {__index = _G})
setfenv(1, newfenv)
print(1)        -- 1 新环境直接继承了全局环境的所有域,好处:可以不需要通过_G来手动调用

  这样,当访问到函数中不存在的变量时,会自动在_G中查找。对于当前函数和_G都存在的变量,可以通过是否用_G显示调用来区分,比如如果有两个a,那么_G.a表示继承来的,a就是当前函数环境的。

  另外,可以通过getfenv(f)函数查看函数所处的环境,默认会返回全局环境_G。


  1. f = 4  
  2. function a()  
  3.     f = 3  
  4.     print(getfenv(0).f, getfenv(1).f, getfenv(2).f, getfenv(3).f)  
  5. end  
  6. A = {}  
  7. setmetatable(A, {__index = _G})  
  8. setfenv(a, A)  
  9.   
  10. function b()  
  11.     f = 2  
  12.     A.a()  
  13. end  
  14. B = {}  
  15. setmetatable(B, {__index = _G})  
  16. setfenv(b, B)  
  17.   
  18. function c()  
  19.     f = 1  
  20.     B.b()  
  21. end  
  22. C = {}  
  23. setmetatable(C, {__index = _G})  
  24. setfenv(c, C)  
  25. c()  

 

只有setfenv了环境。。getfenv才能生效。

相关文章推荐

lua中的setfenv和getfenv

设置函数环境——setfenv   当我们在全局环境中定义变量时经常会有命名冲突,尤其是在使用一些库的时候,变量声明可能会发生覆盖,这时候就需要一个非全局的环境来解决这问题。setf...

lua5.1中的setfenv使用

setenv是在lua5.1中有的改变函数作用域的函数。 用法是setenv(func or number,tbl),第一个参数可以是数字也可以是函数,数字1表示当前的作用于,2表示上一层的作用域,...
  • icyday
  • icyday
  • 2012-10-26 20:05
  • 11645

5.1 setfenv,但5.3可以使用lua_getglobal(l1, "_G");

lua_State *L = luaL_newstate(); luaL_openlibs(L); dostring(L, "function f1() my_var = 100 print('va...

setfenv

https://segmentfault.com/a/1190000002723546 4 辅助库 辅助库为我们用 Lua 与 C 的通信提供了一些方便的函数。基础 API 提供 Lua ...

lua的table+setfenv+setmetatable陷阱

--file1.lua x  = funciton() print("this is x") end ------------- --file2.lua local t = {} ...

Lua中的基本函数库

collectgarbage (opt [, arg]) 功能:是垃圾收集器的通用接口,用于操作垃圾收集器 参数: opt:操作方法标志 “Stop”: 停止垃圾收集器 “Restart”:...

Lua脚本工具

  • 2017-10-12 10:46
  • 48KB
  • 下载

C语言和Lua交互(四)

C语言创建lua table变量

lua for windows完整

  • 2017-09-24 22:11
  • 26.66MB
  • 下载
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)