Python os.environ会引发关键错误吗?

时间:2016-09-01 20:33:49

标签: python python-2.7

我正在使用os.environ.get访问脚本中的环境变量,并且它正在抛出KeyError。它不会从Python提示符中抛出错误。它在OS X 10.11.6上运行,并且是Python 2.7.10。

发生了什么事?

$ python score.py
Traceback (most recent call last):
  File "score.py", line 4, in <module>
    setup_logging()
  File "/score/log.py", line 29, in setup_logging
    config = get_config()
  File "/score/log.py", line 11, in get_config
    environment = os.environ.get('NODE_ENV')
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/UserDict.py", line 23, in __getitem__
    raise KeyError(key)
KeyError: 'NODE_ENV'
$ python -c "import os; os.environ.get('NODE_ENV')"
$

根据要求,这里是score.py

的源代码
from __future__ import print_function

from log import get_logger, setup_logging
setup_logging()
log = get_logger('score')

以及log.py

import json
import os
import sys

from iron_worker import IronWorker
from logbook import Logger, Processor, NestedSetup, StderrHandler, SyslogHandler

IRON_IO_TASK_ID = IronWorker.task_id()

def get_config():
  environment = os.environ.get('NODE_ENV')
  if environment == 'production':
    filename = '../config/config-production.json'
  elif environment == 'integration':
    filename = '../config/config-integration.json'
  else:
    filename = '../config/config-dev.json'

  with open(filename) as f:
    return json.load(f)

def setup_logging():
  # This defines a remote Syslog handler
  # This will include the TASK ID, if defined
  app_name = 'scoreworker'
  if IRON_IO_TASK_ID:
    app_name += '-' + IRON_IO_TASK_ID

  config = get_config()

  default_log_handler = NestedSetup([
    StderrHandler(),
    SyslogHandler(
      app_name,
      address = (config['host'], config['port']),
      level = 'ERROR',
      bubble = True
    )
  ])
  default_log_handler.push_application()

def get_logger(name):
  return Logger(name)

4 个答案:

答案 0 :(得分:10)

尝试跑步:

find . -name \*.pyc -delete

删除.pyc个文件。

研究您的问题我遇到this question,用户遇到了同样的事情:.get()似乎提升了KeyError。在这种情况下,根据this accepted answer,它是由.pyc文件引起的,该文件包含密钥访问dict值的代码(即mydict['potentially_nonexistent_key']),回溯显示了更新的.py文件中使用.get()的代码。我从未听说过这种情况,其中回溯引用了.py文件中的当前代码,但显示了过时的.pyc文件引发的错误,但它似乎在历史记录中至少发生过一次Python ...

这是一个很长的镜头,但值得一试,我想。

答案 1 :(得分:2)

设置环境变量而不导出时遇到类似的错误。因此,如果您这样做:

me@host:/# NODE_ENV=foo

您将得到这个:

me@host:/# python3
Python 3.8.2 (default, Apr 27 2020, 15:53:34) 
[GCC 9.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import os
>>> node_env = os.environ['NODE_ENV']
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib/python3.8/os.py", line 675, in __getitem__
raise KeyError(key) from None
KeyError: 'NODE_ENV'
>>>

但是,如果您这样做:

me@host:/# NODE_ENV=foo
me@host:/# export NODE_ENV

有效:

me@host:/# python3
Python 3.8.2 (default, Apr 27 2020, 15:53:34) 
[GCC 9.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import os
>>> node_env = os.environ['NODE_ENV']
>>> print(node_env)
foo
>>>

答案 2 :(得分:0)

用于Windows删除.pyc文件的命令:

del /S *.pyc

答案 3 :(得分:-5)

我建议你开始调试os.py,例如,在Windows上使用这个实现:

def get(self, key, failobj=None):
    print self.data.__class__
    print key
    return self.data.get(key.upper(), failobj)

如果我用它来测试它:

import os


try:
    os.environ.get('NODE_ENV')
except Exception as e:
    print("-->{0}".format(e.__class__))

os.environ['NODE_ENV'] = "foobar"

try:
    os.environ.get('NODE_ENV')
except Exception as e:
    print("{0}".format(e.__class__))

输出将是:

<type 'dict'>
PYTHONUSERBASE
<type 'dict'>
APPDATA
<type 'dict'>
NODE_ENV
<type 'dict'>
NODE_ENV

所以有意义的是,异常不会产生阅读dict.get文档。

在任何情况下,如果您不想搞砸或调试python模块,请尝试清理* .pyc文件,尝试正确设置NODE_ENV。如果一切都不起作用,请重新启动终端以清理。