Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/EmptyTag/155.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何从Python中读取Perl数据结构?_Python_Perl_Configuration_Data Structures - Fatal编程技术网

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

如何从Python中读取Perl数据结构?,python,perl,configuration,data-structures,Python,Perl,Configuration,Data Structures,我经常看到人们用Perl数据结构代替配置文件;i、 e.仅包含以下内容的单独文件: %config = ( 'color' => 'red', 'numbers' => [5, 8], qr/^spam/ => 'eggs' ); 使用纯Python将这些文件的内容转换为与Python等效的数据结构的最佳方法是什么?目前,我们可以假设没有真正的表达式需要计算,只有结构化数据。使用纯Python是一种要求吗?如果没有,您可以在Perl中加载它并将其转换为

我经常看到人们用Perl数据结构代替配置文件;i、 e.仅包含以下内容的单独文件:

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

使用纯Python将这些文件的内容转换为与Python等效的数据结构的最佳方法是什么?目前,我们可以假设没有真正的表达式需要计算,只有结构化数据。

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

不确定用例是什么。这里是我的假设:您将执行从Perl到Python的一次性转换

Perl有这样的功能

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

config = {
    'color' : 'red',
    'numbers' : [5, 8],
    re.compile( "^spam" ) : 'eggs'
}
所以,我猜这是一堆要替换的RE

  • %variable=(
    变量={
  • );
    }
  • variable=>value
    变量:value
  • qr/../=>
    re.compile(r“…”):值
然而,Python内置的dict
regex作为散列键并没有做任何不寻常的事情。为此,您必须编写自己的
dict
子类,并重写
\uu getitem\uuuu
以分别检查正则表达式键

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 "<stdin>", line 1, in <module>
  File "<stdin>", line 10, in __getitem__
KeyError: "key 'ji' not found"
>>> x['hi']
'eggs'
pat=re.compile(“hi”) >>>a={pat:'eggs'}#本机dict,无特征。 >>>x=PerlLikeDict(a) >>>x['b']='c' >>>x {:‘蛋’,‘b’:‘c’} >>>x['b'] “c” >>>x['ji'] 回溯(最近一次呼叫最后一次): 文件“”,第1行,在 文件“”,第10行,在\uu getitem中__ KeyError:“找不到键'ji'” >>>x['hi'] “鸡蛋”
我也找到了,但它似乎没有得到维护。我想这就是我想要的——一个对Perl做了一些基本解释并将结果作为Python对象传递的模块。如果一个Perl解释器在任何过于复杂的情况下都会失效,那就好了。:-)

我只想将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 JSON:

XML::Simple的效果不太好,因为它将所有内容都视为一个属性,但也许有人可以对此进行改进:

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

我想使用纯Python,但这还是很有帮助的。:)当数据结构被嵌套时,它可能会变得更复杂,这可能需要某种递归解析器。如果它变得更复杂,我们就必须更详细地了解用例。这种东西看起来像是一次性的手工转化。但也许不是。无法从问题中分辨出实际用例是什么。这一总体思路需要一些小的调整。(正则表达式转换有点棘手。)(正则表达式转换的意思是正则表达式被用作散列中的键——将它们更改为re.compile形式是非常重要的。)“正则表达式被用作散列中的键”这意味着什么?PyPerl不是纯Python。这是一个用C编写的python扩展模块。要点是——我想我在寻找类似PyPerl的东西,它是用纯python实现的。:-)对于OP myconfig.pm,它可以是
perl-MJSON-E'do shift;对_json\%config'myconfig.pm
。但是Python不会理解“(?-xism:^spam)”regexp。这是一个非常好的解决方案。试图从perl之外的任何东西中快速解析perl都需要大量的工作。你甚至可以用python将整个过程包装在函数调用中,它只是一个subprocess.Popen和json.load调用。。。有风险的请确保您知道这是应用程序的最佳方式,而且Yaml、XML或平面文件等东西没有比这更好的东西。对,我不建议任何人选择这样做——这是我继承的东西。:-)琐事:Perl本机不支持这一点。所有哈希键都是字符串化的;在Perl中,除了字符串之外,不可能对哈希键使用任何东西。您必须使用类似于模块的方法来解析这样的散列工作,而且由于Perl积极地扰乱散列键-值对的顺序,因此这样一个命令的输出可能定义得很差。如果您的配置文件必须是可执行的,那么您最好编写一个适当的perl模块,其中包含一个子模块和一堆
如果$url=~qr/^spam/,则返回“鸡蛋”行。。。
 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
perl -MXML::Simple -le 'do shift; print XMLout( $CPAN::Config )' MyConfig.pm