Oop Lua:Class方法跳过第一个参数
我试图在Lua中实现一个类,该类应该被实例化。但是,我得到一个错误,函数Oop Lua:Class方法跳过第一个参数,oop,lua,torch,Oop,Lua,Torch,我试图在Lua中实现一个类,该类应该被实例化。但是,我得到一个错误,函数BatchLoader.init的输入参数被移位。我是否缺少实现一个self关键字作为python中任何成员函数的参数输入,或者类定义是否有其他错误 整个类代码如下所示(我去掉了不重要的部分): 但是,当我创建这个类,然后调用函数BatchLoader.init时,似乎y被解释为X,y被解释为sid等等。同样地,batch_size的输入被解释为sids,其中每个参数都从实际参数“移开” 下面的代码就是我在进入该BatchL
BatchLoader.init
的输入参数被移位。我是否缺少实现一个self
关键字作为python中任何成员函数的参数输入,或者类定义是否有其他错误
整个类代码如下所示(我去掉了不重要的部分):
但是,当我创建这个类,然后调用函数BatchLoader.init
时,似乎y被解释为X,y被解释为sid等等。同样地,batch_size
的输入被解释为sids
,其中每个参数都从实际参数“移开”
下面的代码就是我在进入该BatchLoader.init
之前调用的代码。这里的所有内容都按预期打印
local BatchLoader = require "../datahandler/BatchLoader.lua"
local trainLoader = BatchLoader:new()
print(X_data[{{1, 62000}, {}, {}}]:size()) -- Prints size(62000, 8, 16)
print(y_data[{{1, 62000}, {}}]:size()) -- Prints size(62000, 1)
print(sid_data[{{1, 62000}, {}}]:size()) -- Prints size(62000, 1)
local X_train, y_train, sid_train = trainLoader.init(
X_data[{{1, a}, {}, {}}],
y_data[{{1, a}, {}}],
sid_data[{{1, a}, {}}],
10, true)
我的问题是:这里的类声明有什么问题吗?这是我在Lua中的第一个OOP代码,非常感谢您的任何想法或帮助!:) 在Lua中,此语法:
o:f(x, y)
这是语法糖:
o.f(self, x, y)
这对于定义和调用都是正确的。在这里,您使用冒号语法定义init
,并使用点语法调用它,因此它将不起作用,因为第一个参数将变成self
,而其他参数将被一个关闭。解决方案是如下调用init
:
local X_train, y_train, sid_train = trainLoader:init(
X_data[{{1, a}, {}, {}}],
y_data[{{1, a}, {}}],
sid_data[{{1, a}, {}}],
10, true)
这解决了这个问题,但请注意,在您的示例中,构造函数也完全被破坏。因为您使用冒号语法定义它,所以它总是返回BatchLoader
表本身,而不是新实例。因为它是一个类方法,所以您应该编写它并使用点语法调用它:
function BatchLoader.new()
local self = setmetatable({}, BatchLoader)
self.epoch_done = false
return self
end
local trainLoader = BatchLoader.new()
或者简单地说:
function BatchLoader.new()
return setmetatable({epoch_done = false}, BatchLoader)
end
然后您还可以使用点语法调用它:
function BatchLoader.new()
local self = setmetatable({}, BatchLoader)
self.epoch_done = false
return self
end
local trainLoader = BatchLoader.new()
为了理解这些内容,如果您还没有完成,我强烈建议您购买最新版本的Lua编程,并阅读有关面向对象编程的部分。在Lua中,以下语法:
o:f(x, y)
这是语法糖:
o.f(self, x, y)
这对于定义和调用都是正确的。在这里,您使用冒号语法定义init
,并使用点语法调用它,因此它将不起作用,因为第一个参数将变成self
,而其他参数将被一个关闭。解决方案是如下调用init
:
local X_train, y_train, sid_train = trainLoader:init(
X_data[{{1, a}, {}, {}}],
y_data[{{1, a}, {}}],
sid_data[{{1, a}, {}}],
10, true)
这解决了这个问题,但请注意,在您的示例中,构造函数也完全被破坏。因为您使用冒号语法定义它,所以它总是返回BatchLoader
表本身,而不是新实例。因为它是一个类方法,所以您应该编写它并使用点语法调用它:
function BatchLoader.new()
local self = setmetatable({}, BatchLoader)
self.epoch_done = false
return self
end
local trainLoader = BatchLoader.new()
或者简单地说:
function BatchLoader.new()
return setmetatable({epoch_done = false}, BatchLoader)
end
然后您还可以使用点语法调用它:
function BatchLoader.new()
local self = setmetatable({}, BatchLoader)
self.epoch_done = false
return self
end
local trainLoader = BatchLoader.new()
为了理解这些东西,如果您还没有做过,我强烈建议您购买最新版本的Lua编程,并阅读面向对象编程部分。方法语法(使用foo:bar
而不是foo.bar
)自动引入self
参数
在函数定义上,函数Foo:bar(…)
相当于函数Foo.bar(self…)
。在函数调用中,foo:bar(…)
大致相当于foo.bar(foo,…)
(后者计算foo
两次)
让我们来分析一下您的代码:
function BatchLoader:new()
setmetatable({}, BatchLoader) -- creates a table & throws it away
self.epoch_done = false -- self is the hidden first argument
return self
end
local trainLoader = BatchLoader:new() -- i.e. BatchLoader.new( BatchLoader )
这意味着你在有效地跑步
function BatchLoader:new()
setmetatable({}, BatchLoader)
BatchLoader.epoch_done = false
return BatchLoader
end
这肯定不是你想要的。做你想做的事情的几种方法是
-- fixed creation scheme
function BatchLoader.new( )
local self = { epoch_done = false }
return setmetatable( self, BatchLoader )
end
-- acceptable uses:
local trainLoader = BatchLoader.new( )
local trainLoader = BatchLoader:new( ) -- ignores passed self
或
或者其他很多选择
您同样混淆了另一个调用的方法表示法:
function BatchLoader:init(X, y, sids, batch_size, argshuffle)
很好,相当于
function BatchLoader.init(self, X, y, sids, batch_size, argshuffle)
而你却错误地称之为
local X_train, y_train, sid_train =
trainLoader.init( X, y, ... )
(看看为什么一切都变了?)
使用trainLoader:init(X,y,…)
将trainLoader
传递为self方法语法(使用foo:bar
而不是foo.bar
)自动引入self
参数
在函数定义上,函数Foo:bar(…)
相当于函数Foo.bar(self…)
。在函数调用中,foo:bar(…)
大致相当于foo.bar(foo,…)
(后者计算foo
两次)
让我们来分析一下您的代码:
function BatchLoader:new()
setmetatable({}, BatchLoader) -- creates a table & throws it away
self.epoch_done = false -- self is the hidden first argument
return self
end
local trainLoader = BatchLoader:new() -- i.e. BatchLoader.new( BatchLoader )
这意味着你在有效地跑步
function BatchLoader:new()
setmetatable({}, BatchLoader)
BatchLoader.epoch_done = false
return BatchLoader
end
这肯定不是你想要的。做你想做的事情的几种方法是
-- fixed creation scheme
function BatchLoader.new( )
local self = { epoch_done = false }
return setmetatable( self, BatchLoader )
end
-- acceptable uses:
local trainLoader = BatchLoader.new( )
local trainLoader = BatchLoader:new( ) -- ignores passed self
或
或者其他很多选择
您同样混淆了另一个调用的方法表示法:
function BatchLoader:init(X, y, sids, batch_size, argshuffle)
很好,相当于
function BatchLoader.init(self, X, y, sids, batch_size, argshuffle)
而你却错误地称之为
local X_train, y_train, sid_train =
trainLoader.init( X, y, ... )
(看看为什么一切都变了?)
使用trainLoader:init(X,y,…)
将trainLoader
传递为self
您已经用冒号(而不是点)定义了BatchLoader:init
,所以您也必须用冒号来传递trainLoader:init
。非常感谢,我的错误,太愚蠢了!您还可以编写类似于函数Foo.init(…)local的代码,如果…==Foo然后uu,a,b=。。。否则a,b=。。。end print(a,b)end
您已经用冒号(而不是点)定义了BatchLoader:init
,所以您必须使用trainLoader:init
和冒号。非常感谢,我的错误,太愚蠢了!您还可以编写类似于函数Foo.init(…)local的代码,如果…==Foo然后uu,a,b=。。。否则a,b=。。。结束打印(a、b)结束