abspath returns different results when py_compile input path is different in Python?

246 views Asked by At

I want to know abspath of python script followed by steps below.

  1. built it to byte code by py_compile.
  2. execute it to check abspath.

But I got 2 results when I execute it.I found the results based on the path of script followed by py_compile.

Here is my script test.py :

import os
import inspect

print os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe())))

Build it with py_compile, then got 2 results when I enter different path of test.py:

1.enter the folder and compile with only script name.Then chdir to execute

[~]cd /usr/local/bin/
[/usr/local/bin/]python -m py_compile test.py
[/usr/local/bin/]cd ~
[~]python /usr/local/bin/test.pyc
/home/UserXX

2.In other folder and compile with absolute script name.

[~]python -m py_compile /usr/local/bin/test.py
[~]python /usr/local/bin/test.pyc
/usr/local/bin

how come got 2 different results?

1

There are 1 answers

1
atline On

When we want to get the path of one python file, typically we can use any of following methods:

1.

a)

import os
import inspect
print os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe()))).replace('\\', '/')

b)

import os
import inspect
print os.path.dirname(os.path.abspath(inspect.stack()[0][1])).replace('\\', '/')

2.

a)

import os
import sys
print os.path.dirname(os.path.abspath(__file__)).replace('\\', '/')

b)

import os
import sys
print os.path.dirname(os.path.abspath(sys.argv[0])).replace('\\', '/')

For most of scenarios, we use 1 is enough, we seldom to use inspect like 2, as inspect maybe slower.

When will we use 2? Say use inspect to get file path?

One scenario I can remember is execfile, when fileA.py execfile fileB.py in its program, and fileA & fileB not in the same folder. (Maybe more scenario)

Then if we use __file__ in fileB.py, you will find its directory is just same as fileA.py, because here the directory will be the caller's directory. Then we had to use inspect to get fileB.py's directory.

Anyway, for your situation, if your test.py just at the top of callgraph, just suggest you to use __file__, it's quicker, no need to use inspect. With this if you use -m py_compile, it works for you.

Finally, why inspect not work with -m py_compile?

Unfortunately, I did not find official document to explain this. But suppose your test.py is in the folder tt, then let's do cd ..; python -m py_compile tt/test.py, you will get a test.pyc in tt folder.

Let open this pyc file, although you will see something not suitable for man to read, you still can find some clue: One line is something like: currentframe(^@^@^@^@(^@^@^@^@(^@^@^@^@s^G^@^@^@tt/a.pyt

Do you see the folder name tt already in pyc file? If you use inspect.stack() to test, it will more clear, print inspect.stack()[0][1] will always take your current compile folder in pyc file if you use -m py_compile. This directly means during the process of py_compile, something was fixed to pyc file. This something I call fix makes you can just run your program in the same folder you do -m py_compile.

Hope this can give you some clue & helps you.