2016-10-09 4 views
1

В этом коде here они используют os.environ для получения значения переменной окружения, а затем сразу же проверяют, является ли это экземпляром своих пользовательских классов.Может ли Python «os.environ.get» возвращать нестроку?

value = os.environ.get(variable) 
... 
elif isinstance(value, ConfigList) or isinstance(value, ConfigTree): 

Является ли это на самом деле возможно, что value будет экземпляром своих пользовательских классов? Это мертвый код?

+1

Ну, [документация состояния] (https://docs.python.org/3/library/os.html#os.environ) "Объект отображения, представляющий строку среды.". Это исключает многое другое. Python 3 имеет 'os.environb', если вы хотите использовать байты вместо' str'. Я не знаю, как переменная среды была бы 'ConfigList' или' ConfigTree', если только они не определены как 'str' (или' NoneType'). – Evert

+0

Есть ли доказательства того, что код работает? Все это в обработчике исключений, и это не будет действительно сбой, если 'isinstance' всегда терпит неудачу. Возможно, что это всего лишь мертвый код, и никто не заметил, прежде чем вы это сделали;) – zvone

+0

@zvone: Я действительно нашел его, глядя на строки, не охваченные их тестовыми примерами. Я не мог понять, как этот код может быть выполнен. Нечетная часть состоит в том, что этот код существует с самого начала. Этот код не является результатом рефакторинга. Ну, это случается со всеми нами иногда. – movermeyer

ответ

2

Все, что исходит от снаружи, будет просто строкой, я думаю.

С другой стороны, если вы добавляете что-то в среду из кода Python, у вас есть немного больше свободы.

Добавление ничего, но строка до сих пор не удается:

>>> os.environ['a'] = 89 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "C:\Program Files\Python27\lib\os.py", line 420, in __setitem__ 
    putenv(key, item) 
TypeError: must be string, not int 

Однако, вы можете сделать свой собственный класс наследуется от ул:

class C(str): 
    pass 

os.environ['a'] = C() 

В python2 это, кажется, сделать трюк:

>>> type(os.environ['a']) 
<class '__main__.C'> 

Однако в Python 3 это не так. Похоже, он просто сохраняет строку:

>>> type(os.environ['a']) 
<class 'str'> 

Тем не менее, это не объясняет код из pyhocon. Я не вижу, как этот объект может быть помещен в os.environ.

Если они не обезврежены, os.environ ... В этом случае все будет возможно.

+0

Вы видели классы 'Configtree' и' ConfigList'?Подклассы 'OrderDict' и' list' –

+0

@MosesKoledoye Да, я просто написал дополнение к моему ответу. – zvone

+1

> «Однако в Python 3 это не так. Похоже, что он просто сохраняет строку». Вот строка, которая делает это https://github.com/python/cpython/blob/6844dd01dd857ba8e606b5cf4a27cc37b8e2bece/Lib/os.py#L743 – skovorodkin

0

os.environ - простое сопоставление name: value. Это просто добавляет некоторый вкус поверх дикта, чтобы взаимодействовать с окружающей средой. Переменные среды не имеют типа - их простые строки.

Вы можете установить типы переменных в bash, но это не передается другим программам.

$ declare -xi FOO=2 
$ python -c 'import os;print(type(os.environ["FOO"]))' 

Даже когда вы вызываете процесс внутри питона, вы не можете передать другие типы, чем str или bytes.

In [4]: subprocess.check_output(['python', '-c', 'import os;print(os.environ["FOO"])'], env={"FOO": 2}) 
--------------------------------------------------------------------------- 
TypeError         Traceback (most recent call last) 
<ipython-input-4-94f33d136e8f> in <module>() 
----> 1 subprocess.check_output(['python', '-c', 'import os;print(os.environ["FOO"])'], env={"FOO": 2})