Cách đặt biến môi trường trong Python


656

Tôi cần đặt một số biến môi trường trong tập lệnh python và tôi muốn tất cả các tập lệnh khác được gọi từ python để xem các biến môi trường được đặt.

Nếu tôi làm

os.environ["DEBUSSY"] = 1`

Nó phàn nàn rằng đó 1phải là chuỗi.

Tôi cũng muốn biết làm thế nào để đọc các biến môi trường trong python (trong phần sau của tập lệnh) sau khi tôi đặt nó.




Không liên quan đến câu hỏi: Tôi đọc var đó. tên là The Cat
ahmed

Câu trả lời:


787

Biến môi trường phải là chuỗi, vì vậy sử dụng

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

để đặt biến DEBUSSYcho chuỗi 1.

Để truy cập biến này sau, chỉ cần sử dụng:

print(os.environ["DEBUSSY"])

Các tiến trình con tự động kế thừa các biến môi trường của tiến trình cha - không yêu cầu hành động đặc biệt nào từ phía bạn.


20
Trên một số nền tảng, sửa đổi os.envir sẽ không thực sự sửa đổi môi trường hệ thống cho quy trình hiện tại hoặc quy trình con. Xem tài liệu để biết thêm thông tin: docs.python.org/2/l Library / os.html
Evan

8
@Evan Có thể có một số biến thể lịch sử của Unix không hỗ trợ putenv(), nhưng đối với những Unix đó thì bạn không thể làm gì được. Ngay cả phiên bản cũ của AIX và HPUX mà tôi đã làm việc cũng hỗ trợ nó. Nếu bất cứ ai thực sự có thể tìm thấy một máy tính không hỗ trợ nó ngày hôm nay, tôi có nghi ngờ nghiêm trọng rằng họ sẽ có thể chạy Python trên máy tính đó. :)
Sven Marnach

3
Thận trọng: trích dẫn từ tài liệu tham khảo của @ Evan ở trên, Những thay đổi như vậy đối với môi trường ảnh hưởng đến các quy trình con bắt đầu với os.system (), popen () hoặc fork () và execv (). Nói cách khác, hãy nhớ rằng phương pháp này sẽ không sửa đổi cách chương trình của bạn đang chạy, chỉ có cách con cái chương trình của bạn chạy. Đúng, chương trình của bạn có thể thiết lập và đọc lại các biến môi trường, nhưng chỉ từ môi trường mà nó cấu hình cho các phần tử con của nó. Xem thêm: thay đổi môi trường quy trình hiện tại . Cho đến nay tôi vẫn chưa tìm được cách nào cho tập lệnh Python sửa đổi env cha của nó.
MÃ-REaD

1
@SvenMarnach là tuyên bố "quy trình con tự động kế thừa môi trường của quy trình cha mẹ 'đúng với shell như bash.
Krishna Oza

@darth_coder Điều đó đúng với tất cả các quy trình trên các hệ điều hành giống Unix. Tôi không biết về hệ điều hành khác. Lưu ý rằng các biến shell không được lưu trữ trong môi trường trừ khi bạn xuất chúng.
Sven Marnach

114

Bạn có thể cần xem xét một số khía cạnh khác cho độ mạnh của mã;

khi bạn đang lưu trữ một biến có giá trị nguyên như một biến môi trường, hãy thử

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

sau đó để truy xuất, xem xét rằng để tránh lỗi, bạn nên thử

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

có thể thay thế '-1' cho 'Chưa đặt'

vì vậy, để kết hợp tất cả lại với nhau

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)

3
Bạn có thể cho biết cách đặt biến trên máy Linux, mã có giống với tất cả các nền tảng không?
Anurag-Sharma

2
Rất hiếm khi lưu trữ -1 cho một số nguyên bị thiếu. Đặt cược tốt hơn sẽ là myvar = int(os.environ.get('MYVAR')) if os.environ.get('MYVAR', '') != '' else None- theo cách đó sẽ là Không nếu không có số nào được cung cấp
Benjamin Atkin

1
Nếu bạn đang làm việc với số nguyên, -1 có ý nghĩa. Mặc dù tôi có thể sẽ đặt một biến / hằng thành giá trị tôi sẽ sử dụng cho không được đặt (ví dụ value_not_set = '-1':). Sau đó, bạn có thể sử dụngdebussy = int(os.environ.get('DEBUSSY', value_not_set))
yeOldeDataSmythe

67

os.environhoạt động như một từ điển python, vì vậy tất cả các hoạt động từ điển phổ biến có thể được thực hiện. Ngoài các hoạt động getsetđược đề cập trong các câu trả lời khác, chúng tôi cũng có thể chỉ cần kiểm tra nếu một khóa tồn tại. Các khóa và giá trị nên được lưu trữ dưới dạng chuỗi .

Con trăn 3

Đối với python 3, từ điển sử dụng từ khóa trong thay vì has_key

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

Con trăn 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'

Có một điều quan trọng cần lưu ý khi sử dụng os.environ:

Mặc dù các tiến trình con kế thừa môi trường từ tiến trình cha, nhưng tôi đã gặp phải một vấn đề gần đây và nhận ra, nếu bạn có các tập lệnh khác cập nhật môi trường trong khi tập lệnh python của bạn đang chạy, hãy gọi os.environ lại sẽ không phản ánh các giá trị mới nhất .

Trích từ tài liệu :

Ánh xạ này được ghi lại lần đầu tiên mô-đun os được nhập, thường là trong quá trình khởi động Python như là một phần của quá trình xử lý trang web. Những thay đổi đối với môi trường được thực hiện sau thời gian này không được phản ánh trong os.envir, ngoại trừ những thay đổi được thực hiện bằng cách sửa đổi trực tiếp os.envir.

os.environ.data lưu trữ tất cả các biến môi trường, là một đối tượng dict, chứa tất cả các giá trị môi trường:

>>> type(os.environ.data)  # changed to _data since v3.2 (refer comment below)
<type 'dict'>

1
Các biến môi trường của một quy trình được đặt khi quy trình được tạo. Mọi thay đổi được thực hiện sau đó sẽ không ảnh hưởng đến bản sao của biến môi trường. Điều này là phổ biến cho tất cả các quy trình, không chỉ Python. Hơn nữa, os.environ.datađã được đổi tên trong Python 3.2 thành os.environ._data, tiền tố gạch dưới cho thấy rằng bạn không nên đọc nó trực tiếp. Dù sao, os.environ._datasẽ không có giá trị cập nhật nào.
Al Sweigart

Đúng, tôi hiểu rồi. Tôi muốn chia sẻ sự ngạc nhiên ban đầu của tôi với những người khác đang tìm kiếm. Cảm ơn đã chỉ ra bản cập nhật cho tên biến từ 3.2, sẽ cập nhật câu trả lời.
sisanared

21

nếu tôi làm os.envir ["DEBUSSY"] = 1, nó phàn nàn rằng 1 phải là chuỗi.

Sau đó làm

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

Tôi cũng muốn biết làm thế nào để đọc các biến môi trường trong python (trong phần sau của tập lệnh) sau khi tôi đặt nó.

Chỉ cần sử dụng os.environ["DEBUSSY"], như trong

some_value = os.environ["DEBUSSY"]

19

để đặt biến:

Mục Phương thức gán bằng phím:

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

để có được hoặc kiểm tra xem nó có tồn tại hay không,

os.envir là một ví dụ bạn có thể thử cách đối tượng.

Cách 1:

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

sẽ nhận được '1'như là giá trị trả lại

Cách 2:

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

Cách 3:

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

Cách 4:

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

16

Bạn nên gán giá trị chuỗi cho biến môi trường.

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

Nếu bạn muốn đọc hoặc in biến môi trường, chỉ cần sử dụng

print os.environ["DEBUSSY"]

Những thay đổi này sẽ chỉ có hiệu lực đối với quy trình hiện tại nơi nó được chỉ định, nó sẽ không thay đổi giá trị vĩnh viễn. Các tiến trình con sẽ tự động kế thừa môi trường của tiến trình cha.

nhập mô tả hình ảnh ở đây


5
"Những thay đổi này sẽ chỉ có hiệu lực đối với quy trình hiện tại nơi nó được chỉ định, nó sẽ không thay đổi giá trị vĩnh viễn." Điều này đã trả lời một câu hỏi tôi có về phạm vi thiết lập biến môi trường.
spitfiredd

2
Nếu tôi thoát khỏi lớp vỏ trăn, và bộ môi trường os trước đó đã biến mất.
MeadowMuffins

Làm cách nào để đặt biến môi trường trong windows? Tôi đã thử set [<name>=[<value>]]nhưng nó chỉ làm cho nó cho quá trình chạy hiện tại. Khi tôi đóng cmd, nó không tồn tại và ngay cả khi nó mở các chương trình khác cũng không thể thấy nó.
Filip

15

Thế còn os.environ["DEBUSSY"] = '1'? Biến môi trường luôn là chuỗi.


14

Tôi đã cố gắng thêm các biến môi trường. Mục tiêu của tôi là lưu trữ một số thông tin người dùng cho các biến hệ thống để tôi có thể sử dụng các biến đó cho các giải pháp trong tương lai, như là một thay thế cho các tệp cấu hình. Tuy nhiên, phương pháp được mô tả trong đoạn mã dưới đây không giúp tôi chút nào.

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")

Khối mã đơn giản này hoạt động tốt, tuy nhiên, các biến này tồn tại bên trong các quy trình tương ứng sao cho bạn sẽ không tìm thấy chúng trong tab biến môi trường của cài đặt hệ thống windows. Khá nhiều mã trên không phục vụ mục đích của tôi. Vấn đề này được thảo luận ở đây: vấn đề lưu biến

os.environ.putenv(key, value)

Một nỗ lực không thành công. Vì vậy, cuối cùng, tôi đã quản lý để lưu biến thành công bên trong thanh ghi môi trường cửa sổ bằng cách bắt chước các lệnh shell của windows được gói bên trong lớp hệ thống của gói os. Các mã sau đây mô tả nỗ lực thành công này.

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

Tôi hy vọng điều này sẽ hữu ích cho một số bạn.


12

Cần lưu ý rằng nếu bạn cố gắng đặt biến môi trường thành đánh giá bash, nó sẽ không lưu trữ những gì bạn mong đợi. Thí dụ:

from os import environ

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

Điều này sẽ không đánh giá nó giống như trong một cái vỏ, vì vậy thay vì đi /Library/Java/JavaVirtualMachines/jdk1.8.0_144.jdk/Contents/Homenhư một con đường, bạn sẽ có được biểu thức nghĩa đen $(/usr/libexec/java_home).

Đảm bảo đánh giá nó trước khi đặt biến môi trường, như vậy:

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}")

11

Bạn có thể sử dụng os.environtừ điển để truy cập các biến môi trường của bạn.

Bây giờ, một vấn đề tôi gặp phải là nếu tôi cố sử dụng os.systemđể chạy một tệp bó đặt các biến môi trường của bạn (sử dụng lệnh SET trong tệp **. Bat *) thì nó sẽ không thực sự đặt chúng cho môi trường python của bạn (nhưng đối với quá trình con được tạo với os.systemhàm). Để thực sự có được các biến được đặt trong môi trường python, tôi sử dụng tập lệnh này:

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

9

Khi bạn chơi với các biến môi trường (thêm / sửa đổi / loại bỏ biến), một thực hành tốt là khôi phục trạng thái trước đó khi hoàn thành chức năng.

Bạn có thể cần một cái gì đó giống như trình modified_environquản lý bối cảnh mô tả trong câu hỏi này để khôi phục các biến môi trường.

Cách sử dụng cổ điển:

with modified_environ(DEBUSSY="1"):
    call_my_function()
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.