2016-08-22 61 views
0

在Python中,我可以編寫from my_module import *,並且my_module的所有成員都將在本地範圍內可用。例如Python中的「from some_module import *」Lua

我的模塊定義:

my_module = {} 
my_module.a = 1 
my_module.b = 2 

使用在另一個文件:

from my_module import * 
return a + b 
#=> 3 

我能做到這一點在Lua?怎麼樣?

+0

'local my_module = require(「my_module」);本地a,b = my_module.a,my_module.b;返回a + b' –

+0

這更像是'from my_module import a,b'。如果有(極端示例)500個我正在導入的東西呢?我寧願不手動導入它們。 –

回答

1

要獲得在局部範圍內的值,你唯一的選擇是實際MAME他們:

--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's from mymodule import * 
--in main.lua 
require("mymodule") 
print(a + b) 

--in mymodule.lua 
a, b = 1, 2 


--Python's import mymodule 
--in main.lua 
require("mymodule") 
print(mymodule.a + mymodule.b) 

--in mymodule.lua 
mymodule = {a = 1, b = 2} 

這些都是有效的方法,但最常用和最安全的是第一種。

另一種可能性是嘗試改變環境修改_ENV值:

--Python's 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返回的表中,這通常不是一件快樂的事情。

0

這是不可能完全實現的,因爲修改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) 
相關問題