当前位置:  开发笔记 > 编程语言 > 正文

如何从Python中读取Perl数据结构?

如何解决《如何从Python中读取Perl数据结构?》经验,为你挑选了3个好方法。

我经常看到人们使用Perl数据结构代替配置文件; 即仅包含以下内容的独立文件:

%config = (
    'color' => 'red',
    'numbers' => [5, 8],
    qr/^spam/ => 'eggs'
);

使用纯Python将这些文件的内容转换为Python等效数据结构的最佳方法是什么?暂时我们可以假设没有真正的表达式来评估,只有结构化数据.



1> codelogic..:

使用纯Python是一个要求吗?如果没有,您可以在Perl中加载它并将其转换为YAML或JSON.然后使用PyYAML或类似的东西在Python中加载它们.



2> brian d foy..:

我只是将Perl数据结构转换为其他内容.没有看到实际的文件,我的解决方案可能会有一些额外的工作.

如果文件中唯一的东西是一个变量声明(所以,最后没有1;,依此类推),将%config它变成YAML 非常简单:

perl -MYAML -le 'print YAML::Dump( { do shift } )' filename 

do返回的最后一件事是等价的,所以在这一点代码返回哈希键-值对的列表.诸如YAML :: Dump之类的东西喜欢使用引用,所以它们得到关于顶级结构的提示,所以我通过do用花括号括起来将它变成哈希引用.对于您的示例,我将获得此YAML输出:

---
(?-xism:^spam): eggs
color: red
numbers:
  - 5
  - 8

不过,我不知道Python会如何使用字符串化的正则表达式.你真的有一把正则表达式的钥匙吗?我很想知道如何将其用作配置的一部分.


如果文件中有额外的东西,生活会更加艰难.可能有一种非常聪明的方法来解决这个问题,但我使用了同样的想法,但只是对我想要的变量名称进行了硬编码.

我在CPAN.pm模块使用的Perl数据结构上尝试了这个,看起来它很好.唯一的丑陋是它提供的变量名称的前瞻性知识.现在您已经在Perl代码中看到了配置错误,避免使用Python代码犯同样的错误.:)

YAML:

 perl -MYAML -le 'do shift; print YAML::Dump( $CPAN::Config )' MyConfig.pm

JSON:

 perl -MJSON::Any -le 'do shift; my $j = JSON::Any->new; print $j->objToJson( $CPAN::Config )' MyConfig.pm

要么

# suggested by JF Sebastian
perl -MJSON -le 'do shift; print to_json( $CPAN::Config )' MyConfig.pm

XML :: Simple不能很好地工作,因为它将所有内容都视为属性,但也许有人可以对此进行改进:

perl -MXML::Simple -le 'do shift; print XMLout( $CPAN::Config )' MyConfig.pm



3> S.Lott..:

不确定用例是什么.这是我的假设:你将进行从Perl到Python的一次性转换.

Perl有这个

%config = (
    'color' => 'red',
    'numbers' => [5, 8],
    qr/^spam/ => 'eggs'
);

在Python中,它会是

config = {
    'color' : 'red',
    'numbers' : [5, 8],
    re.compile( "^spam" ) : 'eggs'
}

所以,我猜这是一堆替代品

%variable = (variable = {

);}

variable => valuevariable : value

qr/.../ =>re.compile( r"..." ) : value

但是,dict使用正则表达式作为哈希键时,Python的内置功能并没有发生任何异常.为此,您必须编写自己的子类dict,并重写__getitem__以单独检查REGEX键.

class PerlLikeDict( dict ):
    pattern_type= type(re.compile(""))
    def __getitem__( self, key ):
        if key in self:
            return super( PerlLikeDict, self ).__getitem__( key )
        for k in self:
            if type(k) == self.pattern_type:
                if k.match(key):
                    return self[k]
        raise KeyError( "key %r not found" % ( key, ) )

这是使用类似Perl的dict的例子.

>>> pat= re.compile( "hi" )
>>> a = { pat : 'eggs' } # native dict, no features.
>>> x=PerlLikeDict( a )
>>> x['b']= 'c'
>>> x
{<_sre.SRE_Pattern object at 0x75250>: 'eggs', 'b': 'c'}
>>> x['b']
'c'
>>> x['ji']
Traceback (most recent call last):
  File "", line 1, in 
  File "", line 10, in __getitem__
KeyError: "key 'ji' not found"
>>> x['hi']
'eggs'

推荐阅读
爱唱歌的郭少文_
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有