Python中的"from some_module import *"在Lua中的用法
在Python中,我可以写from my_module import *,这样,my_module的所有成员都可以在本地作用域中使用。例如:
我的模块定义:
my_module = {}
my_module.a = 1
my_module.b = 2
在另一个文件中使用:
from my_module import *
return a + b
#=> 3
我能在Lua中这样做吗?如何实现?
这并不完全可行,因为修改 local 值(debug.setlocal 不能定义_新_的局部变量)并不完美。最好的办法是调整你的_环境_,因为污染全局作用域并不是一个好主意,但这并不是非常容易的。
如果仔细地做的话,这实际上可以有些优美地实现。我说是有些,因为总会有一个警告,你必须手动调整你在的函数/块的环境。在 Lua 5.2+ 中,需要 local _ENV = ...。在 Lua 5.1 中,setfenv(1, ...) 将会奏效,并且在视觉上更容易。
接下来,我们可以这样做。我们首先定义一个返回克隆环境的函数。其中 clone 是一个浅表复制函数。
return function (env)
env = clone(env or _G)
return env
end
接着,我们添加自定义的 import 函数,它直接修改我们的新环境,而不像 require 那样返回任何东西。你可以在这里进行很好的复杂化,实现不同的方式来决定如何导入环境,以及如何导入 ('*',例如)。
-- @module: import.lua
return function (env)
env = clone(env or _G)
function env.import (modname, ...)
local args = { ... }
local m = require(modname)
for _, name in next, args
env[name] = m[name]
end
end
return env
end
我们可以这样使用:
local _ENV = require('import')()
-- setfenv(1, require('import')())
import('module_name', 'a', 'b')
return a + b
在小规模上,这需要相当多的开销,只是为了避免这样做:
local module_name = require('module_name')
local a, b = module_name.a, module_name.b
在更大的文档中,它可能会更有用,有很多的导入。导入通常集中在文档的顶部,所以额外的噪音并不那么糟糕。如果你可以将 env 设置为全局值一些地方,看起来会更干净。
local _ENV = env()
import('webserver', 'open', 'status', 'close')
import('database', 'connect', 'query', 'disconnect')
import('json', 'parse', 'stringify')
...
并且也可以用来创建沙箱,假设在重写 import 函数时不使用 require!
local my_env = env { print = print }
my_env.import('my_mod', 'foo', 'bar')
local chunk = loadfile('my_file.lua', 'bt', my_env)
- Lua 虚拟机加密load(string.dump(function)) 后执行失败问题如何解决
- 我想创建一个 Nginx 规则,禁止访问
- 如何将两个不同的lua文件合成一个 东西有点长 大佬请耐心看完 我是小白研究几天了都没搞定
- 如何在roblox studio中1:1导入真实世界的地形?
- 求解,lua_resume的第二次调用继续执行协程问题。
- 【上海普陀区】内向猫网络招募【Skynet游戏框架Lua后端程序员】
- SF爱好求教:如何用lua实现游戏内调用数据库函数实现账号密码注册?
- Lua实现网站后台开发
- LUA错误显式返回,社区常见的规约是怎么样的
- lua5.3下载库失败
- 请问如何实现文本框内容和某个网页搜索框内容连接,并把网页输出来的结果反馈到另外一个文本框上
- lua lanes多线程使用
- 一个kv数据库
- openresty 有没有比较轻量的 docker 镜像
- 想问一下,有大佬用过luacurl吗
- 在Lua执行过程中使用Load函数出现问题
- 为什么 neovim 里没有显示一些特殊字符?
- Lua比较两个表的值(不考虑键的顺序)
- 有个lua简单的项目,外包,有意者加微信 liuheng600456详谈,最好在成都
- 如何在 Visual Studio 2022 中运行 Lua 代码?

要在本地范围内获取这些值,您唯一的选择就是实际上为它们命名:
--in main.lua local mymodule = require("mymodule") local a, b = mymodule.a, mymodule.b --in mymodule.lua return {a = 1, b = 2}或者,另一种选择是:
--in main.lua local a, b = table.unpack(require("mymodule")) --in mymodule.lua return {1, 2}如果您不想实际上为它们命名,那么唯一的方法是将它们放在全局范围内。以下是两个示例:
--Python的from mymodule import * --in main.lua require("mymodule") print(a + b) --in mymodule.lua a, b = 1, 2 --Python的import mymodule --in main.lua require("mymodule") print(mymodule.a + mymodule.b) --in mymodule.lua mymodule = {a = 1, b = 2}这些都是有效的方法,但最常用和安全的是第一种。
另一种可能性是尝试通过修改
_ENV值来更改环境:--Python的from mymodule import * --in main.lua local _ENV = require("mymodule") --in mymodule.lua return {a = 1, b = 2}但是,通过更改环境,您将无法访问全局范围内的所有变量(除非您预先将它们声明为本地变量(
local print = print; _ENV = require("mymodule"); print(a);),或者您将_G表中的所有变量复制到从mymodule返回的表中),这通常不是一件好事。