Perbedaan antara os.getenv dan os.environ.get

159

Apakah ada perbedaan sama sekali antara kedua pendekatan?

>>> os.getenv('TERM')
'xterm'
>>> os.environ.get('TERM')
'xterm'

>>> os.getenv('FOOBAR', "not found") == "not found"
True
>>> os.environ.get('FOOBAR', "not found") == "not found"
True

Mereka tampaknya memiliki fungsi yang sama persis.

André Staltz
sumber

Jawaban:

60

Satu perbedaan diamati (Python27):

os.environmemunculkan pengecualian jika variabel lingkungan tidak ada. os.getenvtidak memunculkan pengecualian, tetapi mengembalikan Tidak Ada

giwyni
sumber
119
OP bertanya tentang os.environ.get()pengembalian None(kecuali ditentukan secara berbeda) dan tidak pernah menimbulkan pengecualian jika ENV. var. tidak ada. Hal-hal membingungkan Anda dengan menggunakan os.environ['TERM']yang bukan tentang pertanyaannya.
Anthon
2
OP pertanyaan bertanya tentang os.environ.get()vs os.getenv()tetapi tubuh juga mencakup os.environvs os.environ.get()sehingga jawaban ini benar dalam setidaknya beberapa cara - tidak lengkap, tapi benar.
FKEinternet
3
Jawaban yang salah dan menyesatkan ini seharusnya mendapat suara negatif. Jawaban selanjutnya adalah yang benar.
RayLuo
80

Lihat utas terkait ini . Pada dasarnya, os.environditemukan pada impor, dan os.getenvmerupakan pembungkus untuk os.environ.get, setidaknya dalam CPython.

EDIT: Untuk menanggapi komentar, dalam CPython, os.getenvpada dasarnya adalah jalan pintas ke os.environ.get; karena os.environdimuat saat impor os, dan hanya kemudian, hal yang sama berlaku untuk os.getenv.

W. Conrad Walden
sumber
1
Memang benar, menurut dokumen resmi: docs.python.org/3/library/os.html
ivanleoncz
1
Dari utas terkait yang terkait: "alasan utama untuk menggunakan os.getenv()[...] adalah ketika Anda ingin mengembalikan nilai default ketika nama variabel lingkungan tidak ditemukan di os.environkunci daripada memiliki KeyErroratau apa pun yang dilemparkan, dan Anda ingin menyimpan beberapa karakter. "
mindthief
35

Dalam Python 2.7 dengan iPython:

>>> import os
>>> os.getenv??
Signature: os.getenv(key, default=None)
Source:
def getenv(key, default=None):
    """Get an environment variable, return None if it doesn't exist.
    The optional second argument can specify an alternate default."""
    return environ.get(key, default)
File:      ~/venv/lib/python2.7/os.py
Type:      function

Jadi bisa kita simpulkan os.getenvhanya pembungkus sederhana saja os.environ.get.

Zulu
sumber
16

Meskipun tidak ada perbedaan fungsional antara os.environ.getdan os.getenv, ada perbedaan besar antara os.putenvdan pengaturan entri aktif os.environ. os.putenvadalah rusak , sehingga Anda harus default untuk os.environ.gethanya untuk menghindari cara os.getenvmendorong Anda untuk menggunakan os.putenvuntuk simetri.

os.putenvperubahan variabel lingkungan OS-tingkat yang sebenarnya, tetapi dengan cara yang tidak muncul melalui os.getenv, os.environ, atau cara stdlib lain memeriksa variabel lingkungan:

>>> import os
>>> os.environ['asdf'] = 'fdsa'
>>> os.environ['asdf']
'fdsa'
>>> os.putenv('aaaa', 'bbbb')
>>> os.getenv('aaaa')
>>> os.environ.get('aaaa')

Anda mungkin harus membuat panggilan ctypes ke tingkat-C getenvuntuk melihat variabel lingkungan nyata setelah menelepon os.putenv. (Meluncurkan subproses shell dan menanyakannya untuk variabel lingkungannya mungkin juga berfungsi, jika Anda sangat berhati-hati untuk melarikan diri dan --norc/ --noprofile/ hal lain yang perlu Anda lakukan untuk menghindari konfigurasi startup, tetapi tampaknya jauh lebih sulit untuk memperbaikinya.)

user2357112 mendukung Monica
sumber
2

Selain jawaban di atas:

$ python3 -m timeit -s 'import os' 'os.environ.get("TERM_PROGRAM")'
200000 loops, best of 5: 1.65 usec per loop

$ python3 -m timeit -s 'import os' 'os.getenv("TERM_PROGRAM")'
200000 loops, best of 5: 1.83 usec per loop
fredrik
sumber
Versi Python mana yang telah Anda uji. Pada 3.7.2, os.getenvhanya pembungkus os.environ.get, jadi saya mendapatkan overhead yang sangat minim.
Preslav Rachev
Itu 3.7.1 di macOS Mojave. Pengaturan waktu cukup konsisten.
fredrik
@ MinimalresachRachev atau tidak itu adalah panggilan fungsi tambahan, jadi ada beberapa overhead. Yang sedang berkata, Anda mungkin tidak perlu mengambil variabel env di tengah loop batin Anda.
pmav99
7
Sama sekali tidak relevan. Optimalisasi mikro dari satu panggilan fungsi ... Aplikasi apa pun harus membaca lingkungan hanya pada bootstrap, menjadikannya semakin tidak relevan.
Victor Schröder
1
BTW, usecadalah mikrodetik di timeit. Perbedaan yang ditemukan dalam pembandingan-mikro ini adalah 0,18 mikrodetik ...
Victor Schröder