通过相对路径加载 Lua 文件

Posted

技术标签:

【中文标题】通过相对路径加载 Lua 文件【英文标题】:Load Lua-files by relative path 【发布时间】:2012-02-27 01:28:31 【问题描述】:

如果我有这样的文件结构:

./main.lua
./mylib/mylib.lua
./mylib/mylib-utils.lua
./mylib/mylib-helpers.lua
./mylib/mylib-other-stuff.lua

main.lua 可以使用完整路径require('mylib.mylib') 加载文件mylib.lua。但在mylib.lua 内部,我还想加载其他必要的模块,我不想总是指定完整路径(例如mylib.mylib-utils)。如果我决定移动文件夹,我将进行大量搜索和替换。有没有办法只使用路径的相对部分?

UPD。如果这很重要,我正在将 Lua 与 Corona SDK 一起使用。

【问题讨论】:

有关使用环境变量的方法,请参阅***.com/questions/5961650/…。 Corona SDK...在 2020 年读起来很可怕。 【参考方案1】:

有一种方法可以推导出文件的“本地路径”(更具体地说,是用来加载文件的字符串)。

如果您需要 lib.foo.bar 中的文件,您可能会这样做:

require 'lib.foo.bar'

然后,当您在所有函数之外时,您可以将文件的路径作为第一个元素(也是唯一的)... 变量。换句话说:

-- lib/foo/bar.lua
local pathOfThisFile = ... -- pathOfThisFile is now 'lib.foo.bar'

现在,要获取“文件夹”,您需要删除文件名。最简单的方法是使用匹配:

local folderOfThisFile = (...):match("(.-)[^%.]+$") -- returns 'lib.foo.'

你有它。现在您可以将该字符串附加到其他文件名并使用它来要求:

require(folderOfThisFile .. 'baz')     -- require('lib.foo.baz')
require(folderOfThisFile .. 'bazinga') -- require('lib.foo.bazinga')

如果您移动bar.luafolderOfThisFile 将自动更新。

【讨论】:

谢谢,这适用于加载文件。但是当我访问模块的公共属性时,我仍然需要指定完整路径(例如lib.foo.bar.some_value)。 这与加载文件无关;它只是反映了你选择如何构建你的 Lua。您可以(例如)在每个要求上返回一个表,并将其存储在本地 var 中:local baz = require(folderOfThisFile .. 'baz') 然后执行 baz.some_value 酷,我不知道 ... 外部函数是用于要求文件的字符串。 @kikito 但即使在同一个库的文件之间,它也会强制使用完整的命名空间路径。如果我声明 mylib.var1 然后在 mylib-utils 我必须指定 some.long.path.mylib.var1 这很尴尬。我想,我会坚持使用一个包含所有内容的目录。它无法维护,但可以工作。 @RockeR :您确定您已正确阅读我的评论吗?它精确地处理了这个问题:它允许您使用baz.some_value 而不是lib.foo.bar.some_value【参考方案2】:

你可以的

package.path = './mylib/?.lua;' .. package.path

或者

local oldreq = require
local require = function(s) return oldreq('mylib.' .. s) end

然后

-- do all the requires
require('mylib-utils')
require('mylib-helpers')
require('mylib-other-stuff')

-- and optionally restore the old require, if you did it the second way
require = oldreq

【讨论】:

奇怪。我已经尝试更改package.path,并认为我做错了什么,因为它说no field package.preload['mylib-utils']no file './mylib/mylib-utils.lua'。但我在 Corona SDK 中使用 Lua,可能它在加载文件方面有一些特殊性。 如果 cwd 已更改(即您从另一个程序/路径运行脚本),这将不起作用。 如果修改后的require() 本身包含的任何内容在内部调用require() 并期望它正常运行,这也将不起作用。【参考方案3】:

我正在使用以下 sn-p。它既适用于使用require 加载的文件,也适用于通过命令行调用的文件。然后使用requireRel 而不是require 用于那些您希望加载相对路径的人。

local requireRel
if arg and arg[0] then
    package.path = arg[0]:match("(.-)[^\\/]+$") .. "?.lua;" .. package.path
    requireRel = require
elseif ... then
    local d = (...):match("(.-)[^%.]+$")
    function requireRel(module) return require(d .. module) end
end

【讨论】:

【参考方案4】:

在 Conky 的 Lua 环境下,我设法将我的 common.lua(在同一目录中)包含为 require(".common")。注意前导点. 字符。

【讨论】:

【参考方案5】:

试试这个:这是我的发现:

module1= require(".\\moduleName")
module2= dofile("..\\moduleName2.lua")
module3 =loadfile("..\\module3.lua")

从当前目录加载。附加一个带有句号前缀的双反斜杠。

要指定上面的目录,请使用两个句号的前缀,并对任何此类目录重复此模式。例如

module4=require("..\\..\\module4")

【讨论】:

以上是关于通过相对路径加载 Lua 文件的主要内容,如果未能解决你的问题,请参考以下文章

需要 Lua 相对路径

有没有更好的方法来要求来自 lua 中相对路径的文件

PyQt5 技巧篇-解决相对路径无法加载图片问题,styleSheet通过"相对"路径加载图片,python获取当前运行文件的绝对路径。

React 页面无法通过带有相对文件路径的 JSON 加载图像

Unity中lua 的 io.open() 文件路径的问题

在 Qt Creator 中加载具有相对路径的文件