ความแตกต่างระหว่าง os.getenv และ os.environ.get


159

มีความแตกต่างระหว่างทั้งสองวิธีหรือไม่?

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

พวกเขาดูเหมือนจะมีฟังก์ชั่นที่แน่นอนเหมือนกัน

คำตอบ:


60

ข้อสังเกตหนึ่งที่แตกต่าง (Python27):

os.environเพิ่มข้อยกเว้นหากไม่มีตัวแปรสภาพแวดล้อม os.getenvไม่ยกข้อยกเว้น แต่ส่งคืนไม่มี


119
OP ถามเกี่ยวกับos.environ.get()สิ่งที่ส่งคืนNone(ยกเว้นกรณีที่ระบุไว้แตกต่างกัน) และไม่ยกข้อยกเว้นถ้า env var ไม่มีอยู่ สิ่งที่คุณสับสนในการใช้os.environ['TERM']ซึ่งไม่ใช่คำถาม
Anthon

2
คำถามของ OP ถามเกี่ยวกับos.environ.get()vs os.getenv()แต่ร่างกายยังรวมถึงos.environvs. os.environ.get()ดังนั้นคำตอบนี้ถูกต้องในบางวิธี - ไม่สมบูรณ์ แต่ถูกต้อง
FKEinternet

3
คำตอบที่ไม่ถูกต้องและทำให้เข้าใจผิดนี้ควรได้รับคะแนนโหวตติดลบ คำตอบต่อไปคือคำตอบที่ถูกต้อง
RayLuo

80

ดูกระทู้ที่เกี่ยวข้องนี้ โดยทั่วไปos.environพบได้ในการนำเข้าและos.getenvเป็นตัวห่อหุ้มos.environ.getอย่างน้อยใน CPython

แก้ไข: เพื่อตอบสนองต่อความคิดเห็นใน CPython os.getenvนั้นเป็นทางลัดไปos.environ.get; นับตั้งแต่os.environมีการโหลดในการนำเข้าและเพียงแล้วเดียวกันถือสำหรับos os.getenv


1
แท้จริงแล้วมันเป็นไปตาม doc อย่างเป็นทางการ: docs.python.org/3/library/os.html
ivanleoncz

1
จากเธรดที่เชื่อมโยงที่เกี่ยวข้อง: "เหตุผลหลักในการใช้os.getenv()[... ] คือเมื่อคุณต้องการให้ส่งคืนค่าเริ่มต้นเมื่อไม่พบชื่อตัวแปรสภาพแวดล้อมในos.environคีย์ของแทนที่จะเป็นแบบKeyErrorโยนหรืออะไรก็ตามและคุณ ต้องการบันทึกตัวละครน้อย "
mindthief

35

ใน Python 2.7 กับ 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

ดังนั้นเราจึงสามารถสรุปได้เป็นเพียงเสื้อคลุมรอบที่เรียบง่ายos.getenvos.environ.get


16

ในขณะที่ไม่มีการทำงานแตกต่างระหว่างos.environ.getและos.getenvมีขนาดใหญ่ความแตกต่างระหว่างและรายการการตั้งค่าos.putenv จะเสียดังนั้นคุณควรใช้ค่าเริ่มต้นเพียงเพื่อหลีกเลี่ยงวิธีการที่ขอให้คุณใช้สำหรับสมมาตรos.environos.putenvos.environ.getos.getenvos.putenv

os.putenvการเปลี่ยนแปลงตัวแปรสภาพแวดล้อมระบบปฏิบัติการระดับที่เกิดขึ้นจริง แต่ในทางที่จะไม่แสดงขึ้นผ่านos.getenv, os.environหรือวิธี STDLIB อื่น ๆ ของการตรวจสอบตัวแปรสภาพแวดล้อม:

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

คุณอาจต้องทำการเรียก ctypes ไปที่ระดับ C getenvos.putenvเพื่อดูตัวแปรสภาพแวดล้อมจริงหลังจากเรียก (การเปิดตัว subprocess เชลล์และขอตัวแปรสภาพแวดล้อมอาจทำงานได้เช่นกันหากคุณระมัดระวังในการหลบหนีและ--norc/ --noprofile/ สิ่งอื่นที่คุณต้องทำเพื่อหลีกเลี่ยงการกำหนดค่าเริ่มต้น แต่ดูเหมือนว่าจะยากขึ้นมากที่จะทำ)


2

นอกจากคำตอบข้างต้น:

$ 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

Python เวอร์ชันใดที่คุณทดสอบด้วย ใน 3.7.2 os.getenvเป็นเพียงเสื้อคลุมos.environ.getดังนั้นฉันจึงมีค่าใช้จ่ายน้อยมาก
Preslav Rachev

นั่นคือ 3.7.1 บน macOS Mojave การกำหนดเวลาค่อนข้างคงที่
เฟรดริก

@PreslavRachev น้อยที่สุดหรือไม่มันเป็นการเรียกฟังก์ชั่นพิเศษดังนั้นจึงมีบางค่าใช้จ่าย ที่ถูกกล่าวว่าคุณอาจไม่จำเป็นต้องเรียกใช้ตัวแปร env ในช่วงกลางของวงในของคุณ
pmav99

7
ไม่เกี่ยวข้องทั้งหมด การเพิ่มประสิทธิภาพขนาดเล็กของการเรียกใช้ฟังก์ชั่นเดียว ... แอปพลิเคชันใด ๆ ควรอ่านสภาพแวดล้อมบน bootstrap ต่อไปเท่านั้นทำให้สิ่งนี้ไม่เกี่ยวข้องมากยิ่งขึ้น
Victor Schröder

1
BTW, usecเป็นมิลลิtimeitใน ความแตกต่างที่พบในการเปรียบเทียบขนาดเล็กนี้คือ 0.18 ไมโครวินาที ...
Victor Schröder
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.