2016-06-21 18 views
2

我正在复活一些孤立的代码,它使用Perl编写,但使用内联Python。对Python模块的调用返回一个数组或Python对象。我真的有如何访问内部数据结构的挣扎 - 如果我尝试直出日志(打印)的数据结构,这似乎给数据很好,但如果我索引顶级阵列(或一个迭代列表)它告诉我它不是一个数组引用。如果我尝试在物体上使用Dumper,我会得到:如何在Perl中使用(或转换,或查看)嵌入式Python对象?

$VAR1 = bless(do{\(my $o = '140162464462376')}, 'Inline::Python::Object'); 

任何想法如何使用(或转换)此对象?

编辑:样本代码如下。这需要一个Google音乐帐户,安装gmusicapi python模块(对于python方面来说,显然是perl方面的内联python)。有趣的是,我编写了一些python代码,并将其转储到Inline Python部分中,但仅转储到API调用返回的数据结构 - 它工作正常(请参阅https://gist.github.com/askvictor/119c24b6fc46a77b349b307457e1a027)。当我居然把API调用到内嵌的Python部分,它打破了4行与Not an ARRAY reference at sample.pl line 4.

use strict; 
use warnings; 

my $data = search("radiohead"); 
print "$data\n"; 
print "$data->{song_hits}\n"; 
print "$data->{song_hits}[0]\n"; 
for my $hit (@{$data->{song_hits}}){ 
    print "$hit->{track}->{title}\n"; 
} 

use Inline Python => <<'END_OF_PYTHON_CODE'; 
import gmusicapi 

USERNAME="[email protected]" 
PASSWORD="sooper_secr3t" 
DEVICE_ID = "12345abcde123" # this can be obtained using https://raw.githubusercontent.com/squeezebox-googlemusic/squeezebox-googlemusic/master/mobile_devices.py 
def search(needle): 
    c = gmusicapi.Mobileclient() 
    c.login(USERNAME, PASSWORD, DEVICE_ID) 
    r = c.search(needle, 2) 
    return r 
END_OF_PYTHON_CODE 
+4

这些对象遵循[内向外模式](http://perldoc.perl.org/perlobj.html#Inside-Out-objects)。你需要使用他们的界面,不幸的是,这并不容易猜测。你能用一小段Python代码创建一个[mcve],它可以在Perl中产生这个输出,所以我们可以试试吗? – simbabque

+0

@simbabque谢谢;已添加示例代码。有趣的是,如果我只在内联部分中抛出代码返回的数据结构,它可以正常工作,但是如果它按照所示运行代码,则会中断。 – askvictor

+0

你的代码没有'strict'和'warnings'吗? – simbabque

回答

1

我有这方面的工作通过py_eval()内部有一个“无用”列表理解。看来Perl的Inline Python不能处理从python代码返回的future.types.newlist.newlist类型的列表。所以这段代码将这些代码转换成普通的旧列表,然后Perl可以处理。

my $song_hits = py_eval("[x for x in $data->{song_hits}]", 0); 
for my $hit (@$song_hits) { 
    print $hit->{track}->{title}; 
    print "\n"; 
} 
+0

很高兴看到你得到它!顺便说一句,'song_hits'在前面需要一个美元符号,'$ song_hits'。 – zdim

相关问题