【问题标题】:Converting a Perl module to JSON with Python使用 Python 将 Perl 模块转换为 JSON
【发布时间】:2017-09-17 13:02:27
【问题描述】:

我有一个 Perl (.pm) 文件,我一直在尝试将其转换为 JSON 表示,以便我可以在其中搜索关键字。

我的脚本目录是/Devices/bin/script.py.pm 文件所在的目录位于上一层,即/Devices/Devices.PMDevices.PM 只是一个静态文件,其中包含结构为字典和列表的数据,如下所示:

mylist = (
    blah => {
        other       =9,
        houses       => 1,
        etc => [
            {   etc   => '5',
                ppl      => '3,
                things       => "etc",
                animals => [ 'blah-228', 'blah-229' ]
            },
            {   etc   => '9',
                ppl      => '5',
                things       => "22",
                animals => [ 'blah-2', 'blah-5' ]
            },
        ],
        partner => 'ets',
        location => 'wherever',
    },
    blah => {
        ppl => 6,
        place => 101,
        things => 'etc',
        animals => 'whatever',
    },

我有:

os.chdir("..")
with open('Devices.pm', 'r') as f:
    json_obj = json.dumps(f)
    print json_obj

但我不断收到TypeError: <open file 'SwitchConfig.pm', mode 'w' at 0x10c1f69c0> is not JSON serializable。我尝试了几种方法都没有运气,包括json.dump(s)。我不断收到不同的错误。我是否没有正确理解我的 .pm 文件结构以便将其转换为 JSON 表示形式?

【问题讨论】:

标签: python json perl


【解决方案1】:

您似乎需要使用 Perl 脚本(或单行脚本)来阅读此内容,然后导出正确的 JSON。

首先,显示的不是有效的 Perl。对于一些基本的语法错误,我将假设在发布时出现拼写错误。

mylist前面也少了一个%;在 Perl 中,变量名称以印记开头,% 表示哈希。我会假设它是张贴的遗漏,但它就在那里。如果没有,你必须解决这个问题。

然后让我使用一个文件data.pm 比如

%mylist = ( 废话=> { 其他 => 9, 房屋=> 1, etc => [ { etc => '5', ppl => '3' }, { etc => '9', ppl => '5' } ] } );

这是已发布数据的简短示例,修正了一些拼写错误。

这是一个用于生成 JSON 的 Perl 脚本。它使用do 将文件作为脚本执行,从而将数据结构(哈希)读入程序。然后JSON::PP 模块用于生成JSON,因为它应该安装在带有 Perl 的系统上。

use warnings;
use strict;
use JSON::PP;

my %data = do './data.pm';

my $data_json = encode_json \%data;

print $data_json, "\n";  # just to see it

my $outfile = 'data.json';
open my $fh, '>', $outfile or die "Can't open $outfile: $!";
print $fh $data_json, "\n";
close $fh;

整个工作在前两行中完成。 JSON::PP 是一个核心模块 (since v5.14),但如果外部依赖不成问题,请使用 JSON,如果已安装,它将使用快速的 JSON::XS

这很适合单线

perl -MJSON::PP -wE'say encode_json { do "./data.pm" }' > data.json

输出重定向到文件的位置。

程序和单行输出(为了便于阅读,换行)

{“废话”:{“其他”:“9”,“房屋”:“1”,“等”: [{"ppl":"3","etc":"5"},{"ppl":"5","etc":"9"}]}}

写入的文件data.json 的内容是什么。

为此,.pm 文件必须只包含有效的 Perl 数据结构。如果变量多于那个哈希值,这将不起作用,因为do 不会返回所有数据。然后你必须通过其他方式处理文件。

【讨论】:

  • 你需要do './data.pm'。如果没有./,它将在@INC 中查找data.pm,而不是当前目录。
  • @melpomene 哦...谢谢,已更正。 (我不知道do 会转到@INC)但是,它的工作原理与我发布的完全一样(?)。 (反正还是更好。)
  • 如果你使用JSON::PP而不是JSON,你的代码不会有任何外部依赖,因为JSON::PP has been a core module since 5.14
  • 它仍然主要工作,因为 perl 默认将 . 添加到 @INC (但在 5.26 中即将消失)。
  • @melpomene 谢谢JSON::PP 注意,这里是正确的。
【解决方案2】:

json.dumps 从 Python 对象(如 {"foo": True})转换为以 JSON 形式表示该对象的字符串(如 '{"foo": true}')。您似乎正试图另辟蹊径,将包含 JSON 的文件转换为 Python 对象;执行此操作的函数是json.load。但是,这仍然行不通,因为Devices.pm 不包含 JSON。您需要编写一个导入 Devices.pm 的 Perl 脚本,然后将其内容转储为实际 JSON,或者在 Python 中为 Perl 编写一个解析器。我推荐第一种方法。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-11-01
    • 2015-04-11
    • 1970-01-01
    • 2011-12-17
    • 2016-06-13
    • 2015-05-24
    • 1970-01-01
    • 2019-06-26
    相关资源
    最近更新 更多