views:

44

answers:

1
from pack.mod import f

How to get from object f information about import - 'pack.mod'

I can get it using f.__module__ but if function def in module where i get this attribute (f.__module__) it return '__main__'. But i need real path here - 'pack.mod'

I found this way to get this information:

inspect.getmodule(f).__file__

then i can sub start path from sys.path, replace / on . and get path like - 'pack.mod' But may be exist some more convenient way?

A: 

What inspect.getmodule(f) does internally, per inspect.py's sources, is essentially sys.modules.get(object.__module__) -- I wouldn't call using that code directly "more convenient", though (beyond the "essentially" part, inspect has a lot of useful catching and correction of corner cases).

Why not call directly inspect.getsourcefile(f)?

Edit: reading between the lines it seems the OP is trying to do something like

python /foo/bar/baz/bla.py

and within bla.py (which is thus being run as __main__) determine "what from or import statement could a different main script use to import this function from within me?".

Problem is, the question is ill-posed, because there might not be any such path usable for the purpose (nothing guarantees the current main script's path is on sys.path when that different main script gets run later), there might be several different ones (e.g. both /foo/bar and /foo/bar/baz might be on sys.path and /foo/bar/baz/__init__.py exist, in which case from baz.bla import f and from bla import f might both work), and nothing guarantees that some other, previous sys.path item might not "preempt" the import attempt (e.g., say /foo/bar/baz is on sys.path, but before it there's also /fee/fie/foo, and a completely unrelated file /fee/fie/foo/bla.py also exists -- etc, etc).

Whatever the purpose of this kind of discovery attempt, I suggest finding an alternative architecture -- e.g., one where from baz.bla import f is actually executed (as the OP says at the start of the question), so that f.__module__ is correctly set to baz.bla.

Alex Martelli
OK, but i need some native way to get info in format ready for importing, not file path witch i need to parse for extract info. It exists or i must parse path anyway?
evg
The `__module__` attribute gives you that path -- you claim it gives `__main__`, but that will never happen when you've done, as you also say, `from path.mod import f` -- only if you're running the file as the main script instead of importing it, and that `from` statement means you **are** importing and so `__module__` works fine.
Alex Martelli
My goal to write logger. i hang it on function as decorator. It dumps all function args it called with at db, function name and module name also written - i need this information to restore function call later with this args on demand. To restore call i need load function before, and that why i need path to load it... I'am targeting that sys.path always same. Mb i need some another way to identify how to load function, m.b full file path and function name better...but in this case i need to analyze file path and sys.path to build valid import path...is it right?
evg
If the function is defined in `__main__` when you log it, it had better be defined exactly the same place when you restore it (i.e, you clearly need to be running the same main script as well as having the same `sys.path`), so `from __main__ import f` in this case is the right answer. No other "path" except `__main__` can ever possibly *guarantee* it will load the same function that `__main__` has defined, as I explained. So just use the `__module__`, whether it's `__main__` or anything else, for your now-stated purposes.
Alex Martelli