Как вызвать функцию Perl в Python

У меня есть несколько функций, написанных в модуле Perl. Мне нужно вызвать эти функции в Python и получить вывод.

Я видел ссылку http://en.wikibooks.org/wiki/Python_Programming/Extending_with_Perl. Я не могу найти модуль Perl, который они импортировали в Python.

Когда я пытаюсь установить pyperl в Linux, он не сможет его найти.

Я могу запустить простой Perl script и получить вывод, но я не могу вызвать функцию, написанную на Perl, и получить вывод.

Ответ 1

Используйте popen, чтобы запустить интерпретатор Perl и выполнить требуемый код. При запуске Perl включите переключатель -m MODULE, чтобы загрузить нужные модули (модули) и -e EXPRESSION, чтобы выполнить нужную функцию. Например, этот код запускает функцию в модуле POSIX и получает результат (строка):

>>> os.popen('''
... perl -mPOSIX -e "print POSIX::asctime(localtime)"
... ''').read()
'Sun Jan 19 12:14:50 2014\n'

Если вам нужно передать более сложные структуры данных между Python и Perl, используйте промежуточный формат, хорошо поддерживаемый на обоих языках, например JSON:

>>> import os, json
>>> json.load(os.popen('''
... perl -e '
...   use POSIX qw(localtime asctime);
...   use JSON qw(to_json);
...   my @localtime = localtime(time);
...   print to_json({localtime => \@localtime,
...                  asctime => asctime(@localtime)});
... '
... '''))
{u'localtime': [10, 32, 12, 19, 0, 114, 0, 18, 0],
 u'asctime': u'Sun Jan 19 12:32:10 2014\n'}

Ответ 2

Сегодня что-то делал, используя модуль под названием perlfunc.py на http://www.boriel.com/files/perlfunc.py.

Протестировано:

  • Python 2.7.12
  • perl 5, версия 22, subversion 1 (v5.22.1), построенная для x86_64-linux-gnu-thread-multi

Небольшая тонкая настройка на perlfunc.py:

  • raise RuntimeError(a.communicate()[1]) (строка 41)
  • удалено "определено" из строки 132

very_old.pl:

#!/usr/bin/perl
sub hello($)
{
   my $d = shift;
   return "Hello, $d!";
}

1;

reuse_very_old_perl_sub.py:

#!/usr/bin/python
from perlfunc import perlfunc, perlreq, perl5lib

@perlfunc
@perlreq('very_old.pl')
def hello(somebody):
    pass


if __name__ == '__main__':
    assert(hello('python-visit-perl') == 'Hello, python-visit-perl!')

Ответ 3

Из представления PyPerler (github):

Я потратил немного свободного времени на написание интерфейса Python → Perl. существующее решение pyperl изначально было написано для очень старых версий Python и больше не компилируется. А пока пишу С Расширения для Python стали намного проще благодаря Cython. я Я подумал, что имеет смысл начать с нуля и написал PyPerler. я К счастью, использовал код PyPerl Perl для упаковки Python объект. На стороне Python все новое.

PyPerler дает вам силу CPAN и ваш (унаследованный?) Perl пакеты, в Python. Использовать Perl так же просто, как:

>>> import pyperler; i = pyperler.Interpreter()
>>> # use a CPAN module
>>> Table = i.use('Text::Table')
>>> t = Table("Planet", "Radius\nkm", "Density\ng/cm^3")
>>> _ = t.load(
...    [ "Mercury", 2360, 3.7 ],
...    [ "Venus", 6110, 5.1 ],
...    [ "Earth", 6378, 5.52 ],
...    [ "Jupiter", 71030, 1.3 ],
... )
>>> for line in t.table(): print line
Planet  Radius Density
        km     g/cm^3 
Mercury  2360  3.7    
Venus    6110  5.1    
Earth    6378  5.52   
Jupiter 71030  1.3

Если вы установите CPAN-пакет Class :: Inspector, то PyPerler даже проведет самоанализ для использования в IPython.