usuario - ¿Cómo puedo leer las estructuras de datos Perl de Python?
pedir un numero al usuario en python (4)
A menudo he visto personas usar estructuras de datos de Perl en lugar de archivos de configuración; es decir, un archivo solitario que contiene solo:
%config = (
''color'' => ''red'',
''numbers'' => [5, 8],
qr/^spam/ => ''eggs''
);
¿Cuál es la mejor manera de convertir los contenidos de estos archivos en estructuras de datos equivalentes a Python, usando Python puro? Por el momento, podemos suponer que no hay expresiones reales para evaluar, solo datos estructurados.
¿El uso de Python puro es un requisito? Si no, puede cargarlo en Perl y convertirlo a YAML o JSON. Luego use PyYAML o algo similar para cargarlos en Python.
Simplemente convertiría la estructura de datos de Perl en otra cosa. Al no ver el archivo real, puede que haya algún trabajo adicional que mi solución no haga.
Si lo único que está en el archivo es la declaración de una variable (por lo tanto, no 1;
al final, y así sucesivamente), puede ser realmente simple convertir su %config
en YAML:
perl -MYAML -le ''print YAML::Dump( { do shift } )'' filename
El do
devuelve lo último que evaluó, por lo que en este pequeño código devuelve la lista de pares clave-valor hash. A cosas como YAML :: Dump le gusta trabajar con referencias para que puedan obtener una pista sobre la estructura de nivel superior, por lo que la hago referencia a hash rodeando el do
con las llaves. Para su ejemplo, obtendría esta salida de YAML:
--- (?-xism:^spam): eggs color: red numbers: - 5 - 8
Sin embargo, no sé cómo le gustará a Python esa expresión regular en corsé. ¿Realmente tienes una clave que es una expresión regular? Me gustaría saber cómo se usa como parte de la configuración.
Si hay elementos adicionales en el archivo, la vida es un poco más difícil. Probablemente haya una forma muy inteligente de evitarlo, pero utilicé la misma idea, pero simplemente codifiqué el nombre de la variable que quería.
Intenté esto en la estructura de datos de Perl que usa el módulo CPAN.pm, y parece que salió bien. La única fealdad es el conocimiento previo del nombre de variable que suministra. Ahora que ha visto el error de configuración en el código Perl, evite cometer el mismo error con el código 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
o
# suggested by JF Sebastian
perl -MJSON -le ''do shift; print to_json( $CPAN::Config )'' MyConfig.pm
XML :: Simple no funciona tan bien porque trata todo como un atributo, pero tal vez alguien pueda mejorarlo:
perl -MXML::Simple -le ''do shift; print XMLout( $CPAN::Config )'' MyConfig.pm
No estoy seguro de cuál es el caso de uso. Esta es mi suposición: harás una conversión única de Perl a Python.
Perl tiene esto
%config = (
''color'' => ''red'',
''numbers'' => [5, 8],
qr/^spam/ => ''eggs''
);
En Python, sería
config = {
''color'' : ''red'',
''numbers'' : [5, 8],
re.compile( "^spam" ) : ''eggs''
}
Entonces, supongo que es un montón de RE para reemplazar
-
%variable = (
convariable = {
-
);
con}
-
variable => value
convariable : value
-
qr/.../ =>
conre.compile( r"..." ) : value
Sin embargo, el dict
incorporado de Python no hace nada inusual con una expresión regular como una clave hash. Para eso, tendría que escribir su propia subclase de dict
y anular __getitem__
para verificar las claves REGEX por separado.
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, ) )
Aquí está el ejemplo del uso de un dict tipo 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''
También encontré PyPerl , pero parece que no se mantiene. Supongo que algo así es lo que estaba buscando, un módulo que hizo una interpretación básica de Perl y pasó el resultado como un objeto de Python. Un intérprete de Perl que muriera en algo demasiado complejo estaría bien. :-)