简体   繁体   中英

How to access Environment variables set in python from perl using Inline::python

I have the below files to use python APIs from perl AnimalsWrapper.py:

import os
class AnimalsWrapper():
    def __init__(self):
        self.name = 'dog '

    def getName(self):
        os.environ['HELLO'] = 'test'
        return self.name + '\n'

AnimalsWrapper.pm:

package AnimalsWrapper;

use parent qw(PythonBase);

package main;
use Inline Python;
our %ENV;

1;

PythonBase.pm

package PythonBase;

use Inline Python => <<"END";

import sys
sys.path.append('<pkgpath>/python3/3.6.3a/bin/python3')
sys.path.append('<pkgpath>/python3/3.6.3a/lib/python3.6/site-packages/')

END

1;

This is the perl script I am using to call python APIs.

#!/usr/bin/perl
use strict;
use warnings;

use lib '<path to the above python code>';

use AnimalsWrapper;
our %ENV;
my $obj = AnimalsWrapper->new();
print $obj->getName();
print $ENV{HELLO}; ==> here this says its uninitalized. 

In this way there is no IPC and while calling python APIs from perl its the same process, but still environment variables are not available. Any help or suggestions here are appreciated.

It's a one-way trip from shell to Perl to Python. Environments cannot pollute their wrapping environments, or terrible things could happen. As a user, you would not be able to trust what would happen if you run a command when your environment can be changed by another process.

You can either delegate full control of the environment somewhere higher up, say in your shell environment, or you need an out-of-band method to return the properties, for example by writing a shell file (slow.) or writing to a socket (complicated).

For comprehension and maximum predictability, I would prefer $ENV control in the parent shell. Hopefully you have considered pyenv and virtualenv as ways to manage custom python installations.

Otherwise you could execute one-liners in your wrapper that would return these values, for example:

my $python_path = exec('which python')

or

my $python_path = exec('python -c "import sys; print(sys.executable)"')

My preference is to let virtualenv do the work, but I suspect your situation is non-ideal.

Enviorment varables are imported when you run the program. You can modify them at runtime, they will only be set for the program's enviorment. eg, your bash session env vars will not be modified. https://perldoc.perl.org/5.32.0/Env.html

#!/usr/bin/perl
use strict;
use warnings;

use lib '<path to the above python code>';
use AnimalsWrapper;

$ENV{"HELLO"} = "hello_text";
my $obj = AnimalsWrapper->new();
print $obj->getName();
print $ENV{"HELLO"}; 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM