idl:动态地将关键字传递给isa函数来测试read_csv读取的结构

时间:2014-11-28 04:30:37

标签: idl-programming-language

我正在使用IDL 8.4。我想使用isa()函数来确定read_csv()读取的输入类型。我想使用/ number,/ integer,/ float和/ string作为一些字段,我想确保浮点数,其他是整数和其他我不在乎。我可以这样做,但它对人眼来说不太可读。

str = read_csv(filename, header=inheader)
; TODO check header
if not isa(str.(0), /integer) then stop
if not isa(str.(1), /number) then stop
if not isa(str.(2), /float) then stop

我希望我能做类似

的事情
expected_header = ['id',       'x',       'val']
expected_type   = ['/integer', '/number', '/float']
str = read_csv(filename, header=inheader)
if not array_equal(strlowcase(inheader), expected_header) then stop
for i=0l,n_elements(expected_type) do
  if not isa(str.(i), expected_type[i]) then stop
endfor

以上不起作用,因为'/ integer'是字面意思的,我猜isa()正在寻找命名结构。你怎么能做类似的事情?

理想情况下,我想根据从文件中读取的标题来选择预期类型,这样只要标题指定了期望的字段,脚本仍然有用。

编辑:

我的初步解决方案是为ISA()编写一个包装器。不是很漂亮,但做了我想要的......如果有更清洁的解决方案,请告诉我。

另外,read_csv被定义为只返回long,long64,double和string中的一个,所以我可以编写函数来测试这个限制。但我只想让它一般工作,以便我可以将它们重用于其他类似的情况。

function isa_generic,var,typ
; calls isa() http://www.exelisvis.com/docs/ISA.html with keyword
; if 'n', test /number
; if 'i', test /integer
; if 'f', test /float
; if 's', test /string
  if typ eq 'n' then return, isa(var, /number)
  if typ eq 'i' then  then return, isa(var, /integer)
  if typ eq 'f' then  then return, isa(var, /float)
  if typ eq 's' then  then return, isa(var, /string)
  print, 'unexpected typename: ', typ
  stop
end

2 个答案:

答案 0 :(得分:1)

IDL具有一些有限的反射能力,这将完全符合您的要求:

expected_types =  ['integer', 'number', 'float']
expected_header = ['id',      'x',      'val']
str = read_csv(filename, header=inheader)
if ~array_equal(strlowcase(inheader), expected_header) then stop
foreach type, expected_types, index do begin
    if ~isa(str.(index), _extra=create_struct(type, 1)) then stop
endforeach

如果在你的情况下这真的“更容易阅读”,这是有争议的,因为只有三种情况需要测试。如果有500个案例,那就比编写500个略有不同的行要清晰得多。

这段剪辑使用了一些相当深奥的IDL功能,所以让我解释一下发生了什么:

expected_types只是(字符串)关键字名称的列表,按照它们的使用顺序。

foreach部分迭代expected_types,将关键字字符串放入type变量,迭代计入index

这相当于使用for index = 0, n_elements(expected_types) - 1 do然后使用expected_types[index]而不是type,但foreach循环更容易阅读恕我直言。参考here

_extra是一个特殊关键字,可以传递结构,就像它是一组关键字一样。每个结构的标签都被解释为关键字。参考here

create_struct函数接受一对或多对(字符串)标记名称和(任何类型)值,然后返回具有这些标记名称和值的结构。参考here

最后,我将notbitwise not)替换为~logical not)。这个步骤与foreach vs for一样,在这种情况下不是必需的,但在调试某些类型的代码时可以避免头痛,这些区别很重要。

-

像这样的反光能力可以做得非常多,而且非常方便。他们是其他语言的工作马,但IDL程序员似乎并没有那么多使用它们。以下是我在IDL中使用的常见反射功能的快速列表,其中包含每个文档的链接:

注意:使用execute功能非常小心。它将盲目地执行您(或用户,文件,Web表单等)提供的任何IDL语句。永远不要将不受信任的或Web用户输入提供给IDL execute函数。

答案 1 :(得分:0)

您无法像这样访问关键字,但typename的{​​{1}}参数可能很有用。这是未经测试的,但应该有效:

ISA