33

From my ipython shell, I see a method setdefault in os.environ but it is not documented. http://docs.python.org/library/os.html#os.environ. Is it documented somewhere else?

def setdefault(self, key, failobj=None):
    if key not in self:
        self[key] = failobj
    return self[key]

Can I use this function or write a wrapper for those lines?

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
balki
  • 26,394
  • 30
  • 105
  • 151

2 Answers2

39

The os.environ documentation does state it's a mapping:

A mapping object representing the string environment.

As such it behaves according to the python mapping documentation of which dict is the standard implementation.

os.environ therefor behaves just like the standard dict, it has all the same methods:

>>> import os
>>> len(os.environ)
36
>>> 'USER' in os.environ
True
>>> os.environ.fromkeys
<bound method classobj.fromkeys of <class os._Environ at 0x107096ce8>>

The .setdefault method is documented on the same page as the rest of the mapping methods, and you can use it just fine as is.

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
  • Tagging along here. `setdefault` exists and is usable, but care should be taken about _where one expects_ to get the default value. You may want to explicitly do something like `os.environ['foo'] = os.environ.get('foo', 'my_default')`. [Actually setting the key is guaranteed to use](https://docs.python.org/3/library/os.html#os.environ) [`putenv` where available](https://docs.python.org/3/library/os.html#os.putenv); so the default is set for this _process_ and any subprocesses it might spawn. (Whereas `setdefault` is Python-code-level affecting the behavior of the mapping/dict lookup.) – floer32 Aug 15 '18 at 23:28
  • 2
    @hangtwenty: `os.environ.setdefault(key, default)` is guaranteed to modify the dictionary exactly the same way as `os.environ[key] = os.environ.get(key, default)` would. That's because the `os._Environ` class which backs that dictionary [explicitly ensures this](https://github.com/python/cpython/blob/e6a4755e6793942b950c1595e0c34bd66a0ee13e/Lib/os.py#L707-L710). – Martijn Pieters Aug 16 '18 at 09:08
  • thanks for that info, I guess I was confusing myself! (I had a script I was using where I thought I saw the behavior above but it must have been something else.) – floer32 Aug 20 '18 at 20:42
6

To clarify--- I had to think for a little while as to what this question and answer mean--- the Python.org docs on os.environ don't bother to mention all of the built-in methods for mapping types (such as os.environ which is basically a dictionary to which additional methods have been given).

Instead, they mainly mention the additional methods that they have given to an object in os, named environ and derived from type dict, beyond those that dict already has built in. From a book that I have on Python, the synopsis for any dictionary type is dict.setdefault(key, default=None), and the explanation is that it is similar to get() but it sets dict[key]=default if key is not already in dict.

default is perhaps not well chosen as a name here because it is easily confused with somevariablename= defaultvalue, the normal way of declaring default values in a function declaration. That is, whereas default=None certainly sets a default, it's not clear how setdefault in any sense essentially sets a default, as default may be given any value.

Mike O'Connor
  • 71
  • 1
  • 3