[英]How can I speed up reading from socket for non-constant size data structures? Python
[英]How can I read Perl data structures from Python?
我经常看到人们使用Perl数据结构代替配置文件。 即一个仅包含以下内容的独立文件:
%config = (
'color' => 'red',
'numbers' => [5, 8],
qr/^spam/ => 'eggs'
);
使用纯Python将这些文件的内容转换为等效于Python的数据结构的最佳方法是什么? 目前,我们可以假设没有要评估的真实表达式,只有结构化数据。
是否需要使用纯Python? 如果没有,您可以将其加载到Perl中并将其转换为YAML或JSON。 然后使用PyYAML或类似的东西在Python中加载它们。
我只是将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
不知道用例是什么。 这是我的假设:您将进行一次从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 = {
);
与}
variable => value
带有variable : value
qr/.../ =>
with re.compile( r"..." ) : value
然而,使用正则表达式作为哈希键,Python的内置dict
并不会做任何异常。 为此,您必须编写自己的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的字典的示例。
>>> 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'
我也找到了PyPerl ,但是似乎没有得到维护。 我猜想我正在寻找这样的东西-一个对Perl进行了一些基本解释并将结果作为Python对象传递的模块。 如果Perl解释器死于任何过于复杂的情况,那就很好了。 :-)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.