Cara mengatur variabel lingkungan dalam Python

658

Saya perlu mengatur beberapa variabel lingkungan dalam skrip python dan saya ingin semua skrip lain yang dipanggil dari python untuk melihat set variabel lingkungan.

Jika aku melakukan

os.environ["DEBUSSY"] = 1`

itu mengeluh mengatakan bahwa 1itu harus string.

Saya juga ingin tahu cara membaca variabel lingkungan dengan python (di bagian akhir skrip) setelah saya mengaturnya.

prahallada
sumber
juga terkait: youtu.be/ScyxIfOuSXs?t=61
Yannic Hamann
Tidak terkait dengan pertanyaan: Saya membaca var itu. beri nama The Cat
ahmed

Jawaban:

790

Variabel lingkungan harus berupa string, jadi gunakan

os.environ["DEBUSSY"] = "1"

untuk mengatur variabel DEBUSSYke string 1.

Untuk mengakses variabel ini nanti, cukup gunakan:

print(os.environ["DEBUSSY"])

Proses anak secara otomatis mewarisi variabel lingkungan dari proses induk - tidak diperlukan tindakan khusus dari Anda.

Sven Marnach
sumber
20
Pada beberapa platform, memodifikasi os.environ tidak akan benar-benar mengubah lingkungan sistem baik untuk proses saat ini atau proses anak. Lihat dokumen untuk info lebih lanjut: docs.python.org/2/library/os.html#os.environ
Evan
8
@ Evan Mungkin ada beberapa varian historis Unix yang tidak mendukung putenv(), tetapi bagi mereka Unixen tidak ada yang bisa Anda lakukan. Bahkan AIX dan HPUX versi lama yang saya gunakan tidak mendukungnya. Jika ada orang yang benar-benar dapat menemukan komputer yang tidak mendukungnya hari ini, saya sangat ragu mereka akan dapat menjalankan Python di komputer itu. :)
Sven Marnach
3
Perhatian: mengutip dari referensi @ Evan di atas, Perubahan-perubahan seperti itu pada lingkungan memengaruhi subproses yang dimulai dengan os.system (), popen () atau fork () dan execv (). Dengan kata lain, perlu diingat bahwa pendekatan ini tidak akan mengubah cara program Anda berjalan, hanya cara anak-anak program Anda berjalan. Benar, program Anda dapat mengatur dan membaca kembali variabel lingkungan, tetapi hanya dari lingkungan yang dikonfigurasikan untuk anak-anaknya. Lihat juga: mengubah lingkungan proses saat ini . Sejauh ini saya belum menemukan cara untuk skrip Python untuk memodifikasi env induknya.
CODE-REaD
1
@SvenMarnach adalah pernyataan "proses anak secara otomatis mewarisi lingkungan proses induk 'benar untuk shell seperti bash.
Krishna Oza
@darth_coder Memang benar untuk semua proses pada sistem operasi mirip Unix. Saya tidak tahu tentang sistem operasi lain. Perhatikan bahwa variabel shell tidak disimpan di lingkungan kecuali Anda mengekspornya.
Sven Marnach
114

Anda mungkin perlu mempertimbangkan beberapa aspek lebih lanjut untuk ketahanan kode;

ketika Anda menyimpan variabel bernilai integer sebagai variabel lingkungan, cobalah

os.environ['DEBUSSY'] = str(myintvariable)

lalu untuk pengambilan, pertimbangkan bahwa untuk menghindari kesalahan, Anda harus mencoba

os.environ.get('DEBUSSY', 'Not Set')

mungkin gantikan '-1' untuk 'Not Set'

jadi, untuk menyatukan semua itu

myintvariable = 1
os.environ['DEBUSSY'] = str(myintvariable)
strauss = int(os.environ.get('STRAUSS', '-1'))
# NB KeyError <=> strauss = os.environ['STRAUSS']
debussy = int(os.environ.get('DEBUSSY', '-1'))

print "%s %u, %s %u" % ('Strauss', strauss, 'Debussy', debussy)
Menandai
sumber
3
Bisakah Anda tahu bagaimana mengatur variabel pada mesin Linux, apakah kodenya sama untuk semua platform?
Anurag-Sharma
2
Jarang masuk akal untuk menyimpan -1 untuk bilangan bulat yang hilang. Taruhan yang lebih baik adalah myvar = int(os.environ.get('MYVAR')) if os.environ.get('MYVAR', '') != '' else None- dengan cara itu akan menjadi Tidak ada jika tidak ada nomor diberikan
Benjamin Atkin
1
Jika Anda berurusan dengan bilangan bulat, -1 masuk akal. Meskipun saya kemungkinan akan menetapkan variabel / konstan ke nilai yang saya gunakan untuk tidak mengatur (misalnya, value_not_set = '-1') Kemudian, Anda dapat menggunakandebussy = int(os.environ.get('DEBUSSY', value_not_set))
yeOldeDataSmythe
68

os.environberperilaku seperti kamus python, sehingga semua operasi kamus umum dapat dilakukan. Selain getdan setoperasi yang disebutkan dalam jawaban lain, kami juga dapat memeriksa apakah ada kunci. Kunci dan nilai harus disimpan sebagai string .

Python 3

Untuk python 3, kamus menggunakan kata kunci in dan bukannya has_key

>>> import os
>>> 'HOME' in os.environ  # Check an existing env. variable
True
...

Python 2

>>> import os
>>> os.environ.has_key('HOME')  # Check an existing env. variable
True
>>> os.environ.has_key('FOO')   # Check for a non existing variable
False
>>> os.environ['FOO'] = '1'     # Set a new env. variable (String value)
>>> os.environ.has_key('FOO')
True
>>> os.environ.get('FOO')       # Retrieve the value
'1'

Ada satu hal penting yang perlu diperhatikan tentang penggunaan os.environ:

Meskipun proses anak mewarisi lingkungan dari proses induk, saya telah menemukan masalah baru-baru ini dan menemukan, jika Anda memiliki skrip lain yang memperbarui lingkungan saat skrip python Anda berjalan, menelepon os.environlagi tidak akan mencerminkan nilai terbaru .

Kutipan dari dokumen :

Pemetaan ini diambil saat modul os pertama kali diimpor, biasanya selama Python startup sebagai bagian dari pemrosesan site.py. Perubahan lingkungan yang dibuat setelah waktu ini tidak tercermin dalam os.environ, kecuali untuk perubahan yang dilakukan dengan memodifikasi os.environment secara langsung.

os.environ.data yang menyimpan semua variabel lingkungan, adalah objek dict, yang berisi semua nilai lingkungan:

>>> type(os.environ.data)  # changed to _data since v3.2 (refer comment below)
<type 'dict'>
sisanared
sumber
1
Variabel lingkungan suatu proses diatur saat proses dibuat. Setiap perubahan yang dilakukan setelah ini tidak akan mempengaruhi salinan variabel lingkungan proses itu sendiri. Ini umum untuk semua proses, bukan hanya Python. Selanjutnya, os.environ.datadiubah namanya menjadi Python 3.2 menjadi os.environ._data, awalan garis bawah yang menunjukkan bahwa Anda tidak harus membacanya secara langsung. Bagaimanapun, bagaimanapun os.environ._datajuga tidak akan memiliki nilai yang diperbarui.
Al Sweigart
Yap, saya mengerti sekarang. Saya ingin berbagi kejutan awal saya dengan orang lain yang datang mencari. Terima kasih telah menunjukkan pembaruan ke nama variabel sejak 3.2, akan memperbarui jawabannya.
sisanared
21

jika saya melakukan os.environ ["DEBUSSY"] = 1, ia mengeluh mengatakan bahwa 1 harus berupa string.

Lalu lakukan

os.environ["DEBUSSY"] = "1"

Saya juga ingin tahu cara membaca variabel lingkungan dengan python (di bagian akhir skrip) setelah saya atur.

Cukup gunakan os.environ["DEBUSSY"], seperti pada

some_value = os.environ["DEBUSSY"]
Jim Brissom
sumber
19

untuk Mengatur Variabel:

Metode penugasan item menggunakan kunci:

import os    
os.environ['DEBUSSY'] = '1'  #Environ Variable must be string not Int

untuk mendapatkan atau memeriksa apakah ada atau tidak,

karena os.environ adalah contoh Anda dapat mencoba cara objek.

Metode 1:

os.environ.get('DEBUSSY') # this is error free method if not will return None by default

akan mendapatkan '1'nilai pengembalian

Metode 2:

os.environ['DEBUSSY'] # will throw an key error if not found!

Metode 3:

'DEBUSSY' in os.environ  # will return Boolean True/False

Metode 4:

os.environ.has_key('DEBUSSY') #last 2 methods are Boolean Return so can use for conditional statements
Mohideen bin Mohammed
sumber
16

Anda harus menetapkan nilai string ke variabel lingkungan.

os.environ["DEBUSSY"] = "1"

Jika Anda ingin membaca atau mencetak variabel lingkungan gunakan saja

print os.environ["DEBUSSY"]

Perubahan ini hanya akan efektif untuk proses saat ini di mana ia ditugaskan, tidak akan mengubah nilai secara permanen. Proses anak akan secara otomatis mewarisi lingkungan proses induk.

masukkan deskripsi gambar di sini

RejeeshChandran
sumber
5
"Perubahan ini hanya akan efektif untuk proses saat ini di mana ia ditugaskan, itu tidak akan mengubah nilai secara permanen." Ini menjawab pertanyaan yang saya miliki tentang ruang lingkup pengaturan variabel environment.
spitfiredd
2
Jika saya keluar dari shell python, dan lingkungan os set sebelumnya sudah tidak ada.
MeadowMuffins
Bagaimana cara menetapkan variabel lingkungan di windows? Saya mencoba set [<name>=[<value>]]tetapi hanya membuatnya untuk proses berjalan saat ini. Ketika saya menutup cmd itu tidak ada dan bahkan ketika itu terbuka, program lain tidak dapat melihatnya.
Filip
15

Bagaimana dengan os.environ["DEBUSSY"] = '1'? Variabel lingkungan selalu bersifat string.

Pencuri
sumber
14

Saya telah mencoba menambahkan variabel lingkungan. Tujuan saya adalah untuk menyimpan beberapa informasi pengguna ke variabel sistem sehingga saya dapat menggunakan variabel-variabel tersebut untuk solusi di masa depan, sebagai alternatif untuk mengkonfigurasi file. Namun, metode yang dijelaskan dalam kode di bawah ini tidak membantu saya sama sekali.

import os
os.environ["variable_1"] = "value_1"
os.environ["variable_2"] = "value_2"
# To Verify above code
os.environ.get("variable_1")
os.environ.get("variable_2")

Blok kode sederhana ini berfungsi dengan baik, namun, variabel-variabel ini ada di dalam masing-masing proses sehingga Anda tidak akan menemukannya di tab variabel lingkungan dari pengaturan sistem windows. Cukup banyak kode di atas tidak memenuhi tujuan saya. Masalah ini dibahas di sini: variabel save problem

os.environ.putenv(key, value)

Upaya gagal lainnya. Jadi, akhirnya, saya berhasil menyimpan variabel dengan sukses di dalam register lingkungan jendela dengan meniru perintah shell windows yang dibungkus dalam kelas sistem paket os. Kode berikut menjelaskan upaya yang berhasil ini.

os.system("SETX {0} {1} /M".format(key, value))

Saya harap ini akan bermanfaat bagi sebagian dari Anda.

Sourabh Desai
sumber
12

Perlu dicatat bahwa jika Anda mencoba mengatur variabel lingkungan ke evaluasi bash, itu tidak akan menyimpan apa yang Anda harapkan. Contoh:

from os import environ

environ["JAVA_HOME"] = "$(/usr/libexec/java_home)"

Ini tidak akan mengevaluasinya seperti di shell, jadi alih-alih mendapatkan /Library/Java/JavaVirtualMachines/jdk1.8.0_144.jdk/Contents/Homesebagai jalur Anda akan mendapatkan ekspresi literal $(/usr/libexec/java_home).

Pastikan untuk mengevaluasinya sebelum mengatur variabel lingkungan, seperti:

from os import environ
from subprocess import Popen, PIPE

bash_variable = "$(/usr/libexec/java_home)"
capture = Popen(f"echo {bash_variable}", stdout=PIPE, shell=True)
std_out, std_err = capture.communicate()
return_code = capture.returncode

if return_code == 0:
    evaluated_env = std_out.decode().strip()
    environ["JAVA_HOME"] = evaluated_env
else:
    print(f"Error: Unable to find environment variable {bash_variable}")
Josh Correia
sumber
11

Anda dapat menggunakan os.environkamus untuk mengakses variabel lingkungan Anda.

Sekarang, masalah yang saya miliki adalah bahwa jika saya mencoba menggunakan os.systemuntuk menjalankan file batch yang menetapkan variabel lingkungan Anda (menggunakan perintah SET dalam file **. Bat *) itu tidak akan benar-benar mengaturnya untuk lingkungan python Anda (tetapi untuk proses anak yang dibuat dengan os.systemfungsi). Untuk benar-benar mendapatkan variabel yang ditetapkan di lingkungan python, saya menggunakan skrip ini:

import re
import system
import os

def setEnvBat(batFilePath, verbose = False):
    SetEnvPattern = re.compile("set (\w+)(?:=)(.*)$", re.MULTILINE)
    SetEnvFile = open(batFilePath, "r")
    SetEnvText = SetEnvFile.read()
    SetEnvMatchList = re.findall(SetEnvPattern, SetEnvText)

    for SetEnvMatch in SetEnvMatchList:
        VarName=SetEnvMatch[0]
        VarValue=SetEnvMatch[1]
        if verbose:
            print "%s=%s"%(VarName,VarValue)
        os.environ[VarName]=VarValue
Ricardo Alejos
sumber
9

Saat Anda bermain dengan variabel lingkungan (tambah / ubah / hapus variabel), praktik yang baik adalah mengembalikan status sebelumnya pada penyelesaian fungsi.

Anda mungkin memerlukan sesuatu seperti yang modified_environdijelaskan oleh manajer konteks dalam pertanyaan ini untuk memulihkan variabel lingkungan.

Penggunaan klasik:

with modified_environ(DEBUSSY="1"):
    call_my_function()
Laurent LAPORTE
sumber