Một thực hành tốt để kiểm tra nếu một biến môi trường tồn tại hay không?


129

Tôi muốn kiểm tra môi trường của tôi để biết sự tồn tại của một biến, giả sử "FOO", trong Python. Đối với mục đích này, tôi đang sử dụng osthư viện tiêu chuẩn. Sau khi đọc tài liệu của thư viện, tôi đã tìm ra 2 cách để đạt được mục tiêu của mình:

Cách 1:

if "FOO" in os.environ:
    pass

Cách 2:

if os.getenv("FOO") is not None:
    pass

Tôi muốn biết phương pháp nào, nếu một trong hai, là một điều kiện tốt / ưa thích và tại sao.


Nó chủ yếu dựa trên ý kiến. Cả hai đều phục vụ cùng một mục đích. Tôi sẽ thích phương pháp 1 vì nó sạch hơn
Moinuddin Quadri

1
Tôi không thể nói có gì trong đó. Chọn một (lật một đồng xu?) Và đánh giá lại sau nếu nó không hoạt động. Thành thật mà nói tôi nghĩ rằng bạn đã dành nhiều thời gian để gõ câu hỏi này hơn là bạn tiết kiệm bằng cách nào!
jonrsharpe

1
@Ayoub: Tôi nghĩ bạn đã quên xem câu hỏi "Thực hành tốt để kiểm tra xem một biến môi trường có tồn tại hay không trong Python?"
Moinuddin Quadri

1
Ý kiến ​​dựa. Cú pháp của Phương pháp 1 phục vụ tốt hơn, vì bạn hỏi nếu footrong vv env, không phải nếu tìm kiếm fookết quả trong Nonecác giá trị.
Uriel

1
Nhưng cách đó có thể không rõ ràng, trừ khi bạn là người Hà Lan ...
jonrsharpe

Câu trả lời:


168

Sử dụng đầu tiên; nó trực tiếp cố gắng kiểm tra nếu một cái gì đó được xác định trong environ. Mặc dù hình thức thứ hai hoạt động tốt như nhau, nhưng nó thiếu về mặt ngữ nghĩa vì bạn lấy lại giá trị nếu nó tồn tại và chỉ sử dụng nó để so sánh.

Bạn đang cố gắng để xem nếu có điều gì đang hiện diện trong environ , tại sao bạn sẽ có được chỉ để so sánh nó và sau đó quăng nó đi ?

Đó chính xác là những gì getenv:

Nhận một biến môi trường , trả lại Nonenếu nó không tồn tại. Đối số thứ hai tùy chọn có thể chỉ định một mặc định thay thế.

(điều này cũng có nghĩa là séc của bạn chỉ có thể là if getenv("FOO"))

bạn không muốn có nó , bạn muốn kiểm tra sự tồn tại của nó.

Dù bằng cách nào, getenvchỉ là một trình bao bọc xung quanh environ.getnhưng bạn không thấy mọi người kiểm tra tư cách thành viên trong ánh xạ với:

from os import environ
if environ.get('Foo') is not None:

Để tóm tắt, sử dụng:

if "FOO" in os.environ:
    pass

nếu bạn chỉ muốn kiểm tra sự tồn tại, trong khi, hãy sử dụng getenv("FOO")nếu bạn thực sự muốn làm gì đó với giá trị bạn có thể nhận được.


2
Cảm ơn lời giải thích của bạn. Tôi sẽ ghi nhớ điều này.
Kshitij Saraogi

28

Có một trường hợp cho một trong hai giải pháp, tùy thuộc vào những gì bạn muốn làm có điều kiện dựa trên sự tồn tại của biến môi trường.

Trường hợp 1

Khi bạn muốn thực hiện các hành động khác nhau hoàn toàn dựa trên sự tồn tại của biến môi trường, mà không quan tâm đến giá trị của nó, giải pháp đầu tiên là cách thực hành tốt nhất. Nó mô tả ngắn gọn những gì bạn kiểm tra: là 'FOO' trong danh sách các biến môi trường.

if 'KITTEN_ALLERGY' in os.environ:
    buy_puppy()
else:
    buy_kitten()

Trường hợp 2

Khi bạn muốn đặt giá trị mặc định nếu giá trị không được xác định trong các biến môi trường, giải pháp thứ hai thực sự hữu ích, mặc dù không phải ở dạng bạn đã viết:

server = os.getenv('MY_CAT_STREAMS', 'youtube.com')

hoặc có lẽ

server = os.environ.get('MY_CAT_STREAMS', 'youtube.com')

Lưu ý rằng nếu bạn có một số tùy chọn cho ứng dụng của mình, bạn có thể muốn xem xét ChainMap, điều này cho phép hợp nhất nhiều điểm dựa trên các khóa. Có một ví dụ về điều này trong ChainMaptài liệu:

[...]
combined = ChainMap(command_line_args, os.environ, defaults)

15

Để được sử dụng an toàn

os.getenv('FOO') or 'bar'

Một trường hợp góc với các câu trả lời ở trên là khi biến môi trường được đặt nhưng trống

Đối với trường hợp đặc biệt này, bạn nhận được

print(os.getenv('FOO', 'bar'))
# prints new line - though you expected `bar`

hoặc là

if "FOO" in os.environ:
    print("FOO is here")
# prints FOO is here - however its not

Để tránh điều này chỉ cần sử dụng or

os.getenv('FOO') or 'bar'

Sau đó, bạn nhận được

print(os.getenv('FOO') or 'bar')
# bar

Khi nào chúng ta có các biến môi trường trống?

Bạn đã quên đặt giá trị trong .envtệp

# .env
FOO=

hoặc xuất khẩu dưới dạng

$ export FOO=

hoặc quên đặt nó vào settings.py

# settings.py
os.environ['FOO'] = ''

Cập nhật: nếu nghi ngờ, hãy kiểm tra các lớp lót này

>>> import os; os.environ['FOO'] = ''; print(os.getenv('FOO', 'bar'))

$ FOO= python -c "import os; print(os.getenv('FOO', 'bar'))"

Chữ ký của getenv là def getenv(key, default=None):như vậy nếu vậy sẽ cho phép mặc định so với cú pháp hoặc cú pháp khi bắt đầu
Chris McKee

@Chris McKee thử cái này>>> import os; os.environ['FOO'] = ''; print(os.getenv('FOO', 'bar'))
Levon

Chữ ký phương thức gây hiểu lầm
Chris McKee

1
@Chris McKee, một ví dụ khác$ FOO= python -c "import os; print(os.getenv('FOO', 'bar'))"
Levon

3

Trong trường hợp bạn muốn kiểm tra nếu nhiều biến env không được đặt, bạn có thể làm như sau:

import os

MANDATORY_ENV_VARS = ["FOO", "BAR"]

for var in MANDATORY_ENV_VARS:
    if var not in os.environ:
        raise EnvironmentError("Failed because {} is not set.".format(var))

-1

Nhận xét của tôi có thể không liên quan đến các thẻ được đưa ra. Tuy nhiên, tôi đã được dẫn đến trang này từ tìm kiếm của tôi. Tôi đang tìm kiếm kiểm tra tương tự trong R và tôi đã đưa ra những điều sau đây với sự giúp đỡ của bài đăng @hugovdbeg. Tôi hy vọng nó sẽ hữu ích cho những người đang tìm kiếm giải pháp tương tự trong R

'USERNAME' %in% names(Sys.getenv())
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.