Python(os.environ)에서 환경 변수 가져오기, 추가, 덮어쓰기 및 삭제

사업

환경 변수는 os.environ을 사용하여 Python 프로그램에서 검색, 확인, 설정(추가 또는 덮어쓰기) 및 삭제할 수 있습니다. 환경 변수를 설정하거나 삭제하여 변경한 사항은 Python 프로그램 내에서만 유효합니다. 시스템 환경 변수가 다시 작성된다는 의미는 아닙니다.

다음 정보가 여기에 제공됩니다.

  • os.environ
  • 환경 변수를 가져옵니다.
  • 환경 변수 설정(추가/덮어쓰기)
  • 환경 변수 제거
  • 환경 변수 변경의 영향
  • 환경 변수로 프로세스 전환

os 모듈을 가져와 사용합니다. 표준 라이브러리이므로 추가 설치가 필요하지 않습니다. 하위 프로세스 모듈도 표준 라이브러리에 포함되어 있습니다.

import os
import subprocess

os.environ

os.environ의 유형은 os._Environ입니다.

print(type(os.environ))
# <class 'os._Environ'>

os._Environ은 키와 값의 쌍을 가지는 맵 타입의 객체로 사전(dict type)과 동일한 메소드를 가진다. 환경 변수 이름은 키이고 값은 값입니다.

os.environ의 내용은 os 모듈을 가져올 때 로드됩니다. os.environ의 내용은 프로그램이 실행되는 동안 다른 방법으로 시스템 환경 변수를 변경하더라도 업데이트되지 않습니다.

목록은 print()로 표시됩니다.

# print(os.environ)

사전과 마찬가지로 다음 방법을 사용하거나 in을 사용하여 키와 값의 존재를 확인할 수 있습니다.

  • keys()
  • values()

키와 값의 처리는 기본적으로 사전과 동일합니다. 아래에 예가 나와 있습니다.

환경 변수를 가져옵니다.

os.environ[Environment variable name]
이렇게 하면 환경 변수의 값을 얻을 수 있지만 존재하지 않는 환경 변수 이름을 지정하면 오류(KeyError)가 발생합니다.

print(os.environ['LANG'])
# ja_JP.UTF-8

# print(os.environ['NEW_KEY'])
# KeyError: 'NEW_KEY'

기본값이 존재하지 않는 경우 os.environ의 get() 메소드를 사용하여 기본값을 얻을 수 있습니다. 이것은 사전도 마찬가지입니다.

print(os.environ.get('LANG'))
# ja_JP.UTF-8

print(os.environ.get('NEW_KEY'))
# None

print(os.environ.get('NEW_KEY', 'default'))
# default

os.getenv() 함수도 제공됩니다. 사전의 get() 메서드와 마찬가지로 키가 없으면 기본값을 반환합니다. 이 함수는 환경 변수의 값을 가져오고 확인하려는 경우에 유용합니다.

print(os.getenv('LANG'))
# ja_JP.UTF-8

print(os.getenv('NEW_KEY'))
# None

print(os.getenv('NEW_KEY', 'default'))
# default

환경 변수 설정(추가/덮어쓰기)

os.environ[Environment variable name]
여기에 값을 할당하여 환경 변수를 설정할 수 있습니다.

새 환경 변수 이름을 지정하면 환경 변수를 새로 추가하고, 기존 환경 변수 이름을 지정하면 환경 변수 값을 덮어씁니다.

os.environ['NEW_KEY'] = 'test'

print(os.environ['NEW_KEY'])
# test

os.environ['NEW_KEY'] = 'test2'

print(os.environ['NEW_KEY'])
# test2

문자열 이외의 것을 할당하면 오류(TypeError)가 발생합니다. 숫자 값을 지정하려면 문자열로 지정하십시오.

# os.environ['NEW_KEY'] = 100
# TypeError: str expected, not int

os.environ['NEW_KEY'] = '100'

os.putenv() 함수도 제공됩니다. 그러나 os.putenv()에 의해 설정되면 os.environ의 값은 업데이트되지 않습니다. 따라서 위의 예와 같이 os.environ의 키(환경변수명)를 지정하고 값을 할당하는 것이 바람직하다.

putenv()가 지원되는 경우 os.environ의 항목에 대한 할당은 자동으로 putenv()에 대한 해당 호출로 변환됩니다. 실제로 putenv()에 대한 직접 호출은 os.environ을 업데이트하지 않기 때문에 os.environ의 항목에 할당하는 것이 선호되는 작업입니다.
os.putenv() — Miscellaneous operating system interfaces — Python 3.10.0 Documentation

앞서 언급했듯이 환경 변수를 추가하거나 덮어써서 변경한 사항은 파이썬 프로그램 내에서만 유효합니다. 시스템 환경 변수가 다시 작성된다는 의미는 아닙니다.

값을 변경하면 OS에 따라 메모리 누수가 발생할 수 있습니다.

참고: FreeBSD 및 Mac OS X를 포함한 일부 플랫폼에서는 환경 값을 변경하면 메모리 누수가 발생할 수 있습니다.
os.putenv() — Miscellaneous operating system interfaces — Python 3.10.0 Documentation

이는 OS 자체의 putenv() 사양 때문입니다.

Successive calls to setenv() or putenv() assigning a differently sized value to the same name will result in a memory leak. The FreeBSD seman-tics semantics for these functions (namely, that the contents of value are copied and that old values remain accessible indefinitely) make this bug unavoidable.
Mac OS X Manual Page For putenv(3)

환경 변수 제거

환경 변수를 삭제하려면 os.environ의 pop() 메서드나 del 문의 방법을 사용하세요. 사전과 동일합니다.

다음은 pop()의 예입니다.

pop()은 삭제된 환경 변수의 값을 반환합니다. 기본적으로 존재하지 않는 환경 변수를 지정하면 오류(KeyError)가 발생하지만 두 번째 인수를 지정하면 환경 변수가 존재하지 않는 경우 해당 값을 반환합니다.

print(os.environ.pop('NEW_KEY'))
# 100

# print(os.environ.pop('NEW_KEY'))
# KeyError: 'NEW_KEY'

print(os.environ.pop('NEW_KEY', None))
# None

다음은 del의 예입니다.

환경 변수가 다시 추가된 다음 삭제됩니다. 환경 변수가 없으면 오류(KeyError)가 발생합니다.

os.environ['NEW_KEY'] = '100'

print(os.getenv('NEW_KEY'))
# 100

del os.environ['NEW_KEY']

print(os.getenv('NEW_KEY'))
# None

# del os.environ['NEW_KEY']
# KeyError: 'NEW_KEY'

os.unsetenv() 함수도 제공됩니다. 그러나 os.putenv()와 마찬가지로 os.environ의 값은 os.unsetenv()에 의해 삭제될 때 업데이트되지 않습니다. 따라서 위의 예와 같이 os.environ의 키(환경변수명)를 지정하고 삭제하는 것이 바람직하다.

unsetenv()가 지원되는 경우 os.environ에서 항목을 삭제하면 자동으로 해당하는 unsetenv() 호출로 변환됩니다. 실제로 unsetenv()에 대한 직접 호출은 os.environ을 업데이트하지 않으므로 os.environ에서 항목을 삭제하는 것이 선호되는 작업입니다.
os.unsetenv() — Miscellaneous operating system interfaces — Python 3.10.0 Documentation

환경 변수를 삭제하는 것도 해당 Python 프로그램 내에서만 유효합니다. 시스템 환경 변수는 제거하지 않습니다.

환경 변수 변경의 영향

반복해서 썼듯이 os.environ 환경 변수를 변경(설정 또는 삭제)해도 시스템 환경 변수는 변경되지 않지만 프로그램에서 실행되는 하위 프로세스에는 영향을 미칩니다.

다음 코드는 LANG 환경 변수가 없고 date 명령의 내용이 다르기 때문에 Windows에서 예상대로 작동하지 않습니다.

하위 프로세스 모듈에서 날짜 명령을 호출합니다.

date 명령의 출력 결과는 LANG 환경 변수의 값에 따라 달라집니다.

print(os.getenv('LANG'))
# ja_JP.UTF-8

print(subprocess.check_output('date', encoding='utf-8'))
# 2018年 7月12日 木曜日 20時54分13秒 JST
# 

os.environ['LANG'] = 'en_US'

print(subprocess.check_output('date', encoding='utf-8'))
# Thu Jul 12 20:54:13 JST 2018
# 

설명을 위해 os.environ에서 LANG 환경 변수를 변경했지만 파이썬은 로케일을 제어하는 ​​로케일 모듈을 제공합니다.

환경 변수로 프로세스 전환

환경변수의 값에 따라 프로세스를 전환하는 것도 가능하다.

다음은 언어 설정에서 LANG 환경 변수에 따라 출력을 변경하는 예입니다. 여기에서는 문자열이 지정된 문자열로 시작하는지 확인하기 위해 startswith() 메서드를 사용하고 있지만 정확히 일치하는지 확인하려면 “==”를 사용하여 비교할 수 있습니다.

print(os.getenv('LANG'))
# en_US

if os.getenv('LANG').startswith('ja'):
    print('こんにちは')
else:
    print('Hello')
# Hello

os.environ['LANG'] = 'ja_JP'

if os.getenv('LANG').startswith('ja'):
    print('こんにちは')
else:
    print('Hello')
# こんにちは

또한, 예를 들어 개발 환경 및 프로덕션 환경을 나타내도록 환경 변수를 설정하면 이러한 변수의 값을 가져와 프로세스를 전환할 수 있습니다.