Question

Will the sources in PYTHONPATH always be searched in the very same order as they are listed? Or may the order of them change somewhere?

The specific case I'm wondering about is the view of PYTHONPATH before Python is started and if that differs to how Python actually uses it.

Était-ce utile?

La solution

It's actually moderately complicated. The story starts in the C code, which is what looks at $PYTHONPATH initially, but continues from there.

In all cases, but especially if Python is being invoked as an embedded interpreter (including "framework" stuff on MacOS X), at least a little bit of "magic" is done to build up an internal path string. (When embedded, whatever is running the embedded Python interpreter can call Py_SetPath, otherwise python tries to figure out how it was invoked, then adjust and add lib/pythonX.Y where X and Y are the major and minor version numbers.) This internal path construction is done so that Python can find its own standard modules, things like collections and os and sys. $PYTHONHOME can also affect this process. In general, though, the environment $PYTHONPATH variable—unless suppressed via -E—winds up in front of the semi-magic default path.

The whole schmear is used to set the initial value of sys.path. But then as soon as Python starts up, it loads site.py (unless suppressed via -S). This modifies sys.path rather extensively—generally preserving things imported from $PYTHONPATH, in their original order, but shoving a lot of stuff (like system eggs) in front.1 Moreover, one of the things it does is load—if it exists—a per-user file $HOME/.local/lib/pythonX.Y/sitepackages/usercustomize.py, and that can do anything, there are no guarantees:

$ cat usercustomize.py
print 'hello from usercustomize'
$ python
hello from usercustomize
Python 2.7.5 (default, Jun 15 2013, 11:50:00) 
[GCC 4.2.1 20070831 patched [FreeBSD]] on freebsd9
Type "help", "copyright", "credits" or "license" for more information.
>>> 

If I were to put:

import random, sys
random.shuffle(sys.path)

this would scramble sys.path, putting $PYTHONPATH elements in random order. Arguably this is a case of "ok, you shot yourself in the foot, that's your problem". :-) But anything I import can similarly mess with sys.path, so it's possible for something other than my own usercustomize.py to ruin the desired effect (of $PYTHONPATH ordering being preserved).


1 Footnote (late edit): actually the eggs come from site-packages/site.py, which does its own os.getenv("PYTHONPATH"). So it's even messier, in a way. The general principle applies though: standard code should preserve path order, but you can break it.

Autres conseils

Yes, it will be searched always in the same order as paths are listed in PYTHONPATH, but you can do import sys
sys.path.insert(0, 'path/to/your/module')

It will add your module to the first place in PYTHONPATH check this out http://docs.python.org/2/tutorial/modules.html#the-module-search-path

PYTHONPATH passed to sys.path there any module can modify it before importing another modules.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top