importing: what does "from" do?

Steven D'Aprano steve at pearwood.info
Thu Jan 21 11:22:05 EST 2016


On Fri, 22 Jan 2016 02:12 am, Charles T. Smith wrote:

> On Thu, 21 Jan 2016 07:52:17 -0700, Ian Kelly wrote:
> 
>>> I have no idea what was imported before.  I just want to import
>>> hexdump(). Unfortunately, this does not work:
>>>
>>>   from utilities import hexdump
>>>
>>>     ImportError: cannot import name hexdump

Charles, according to your comments further below, you have already imported
successfully hexdump using:

from hexdump import hexdump


So why not just run that instead?



>> What is utilities? Is it a module on your sys.path?
> 
> 
> Yes.

Does utilities.py contain a function, class or other object
called "hexdump"?


(1) At the interactive interpreter, run:

import utilities
dir(utilities)

Do you see a name "hexdump" listed there? (My guess is, No.)


(2) In your text editor of choice, open the utilities.py file, and search
for "hexdump". Do you see anything by that name? (My guess is No.)


If the answer to either of those questions is Yes, then:

(3) You may be looking at a different file called "utilities.py". Is it
possible that you have two such files, and that you are looking at one, and
Python has picked up the other?

(4) Or possibly you have imported utilities into Python, THEN edited the
file and added hexdump to the file. If so, Python will not see the changes
to the file until you exit the interpreter and restart it.

(You may be able to use the reload() function to see the changes, but it is
sometimes finicky to get that to work the way people expect, it is often
better just to exit and restart.)


>> What makes you think this is caused by circular dependencies? It could
>> be, but you really haven't given us enough information about what
>> utilities is to diagnose that.
> 
> Well, I thought that that's what causes these import problems.


Circular dependencies cause SOME import problems, but not all.


> I just 
> wish that python gave me more information, like the tree of imports that's
> causing the problem.

What do you mean by "the tree of imports"? I don't even know what you might
mean by that.



>>> would you explain to me why I get this:
>>>
>>>   (PDB)hexdump(msg)
>>> *** NameError: name 'hexdump' is not defined
>> 
>> Probably because the name 'hexdump' is not defined.
> 
> 
> If indeed it's not defined, then I wouldn't think there'd be a
> problem importing the module that defines it.


I don't understand this. If hexdump isn't defined, how do you expect to
import something that doesn't exist? Or exists in a place that the
interpreter cannot see, which is effectively the same thing.



>>> P.S. can I get a list of all the loaded symbols and/or modules?

In Python 2, run this:


import __builtin__
names = vars(__builtin__).keys()
names.extend(vars().keys())
print sorted(names)


In Python 3, run this:


import builtins
names = list(vars(builtins).keys())
names.extend(vars().keys())
print(sorted(names))


To see the list of modules which have been loaded from disk and stored in
the cache (but not necessarily imported into your program), run this:

import sys
print(sys.modules)



>> What do you mean by "loaded"? Bound to a name in the main module? In the
>> globals of the current scope? In any module? Try the "dir" or "vars"
>> built-in.
>> 
>> You can get a view of all the *cached* modules by looking in the
>> sys.modules dict.
> 
> 
> as in this?
> 
>   (PDB) pp dict (sys.modules)


Charles, I **strongly** suggest that for day to day interactive exploration
of the Python environment, instead of using the debugger, you use the
ordinary (and quite powerful) Python interactive interpreter. 

At the Python prompt, just type the code you want to execute, and it will be
executed interactively.

(The one major difference between the interactive interpreter and the
non-interactive one is that the interactive interpreter is quite fussy
about blank lines between blocks. For example, you need to leave a blank
line after a function when defining it:


py> def foo():
...     return 42
... x = foo()  # oops, forgot the blank line
  File "<stdin>", line 3
    x = foo()  # oops, forgot the blank line
    ^
SyntaxError: invalid syntax



and you cannot leave blank lines in the middle of a block:


py> def foo():
...     a = 42
...
py>     return a  # oops, the blank line has ended the block
  File "<stdin>", line 1
    return a  # oops, the blank line has ended the block
    ^
IndentationError: unexpected indent




> Okay, quite good.  I have this (among others):
> 
> 
>  'hexdump': <module 'hexdump' from '/home/user/hexdump.pyc'>,
>  'int.hexdump': None,

I'm confused. You have a file hexdump, another file utilities.py containing
hexdump, and now it seems you also have a package directory "int"
containing a file called "hexadump".

How do you expect to keep track of which hexdump you are using?

Also, your package "int" is going to clash with the built-in function "int".
You should rename the package.



> But I suspect the first, at any rate, was loaded because of this in
> my ~/.pdbrc:
> 
>   from hexdump import hexdump
> 
> which wouldn't interfere when running without the debugger (that module
> in my sys.path but nowhere near my project)

If it is in sys.path, then it is available to your project.



> I have this in my project:
> 
>   int/__init__.py
> 
> But:
> 
>   $ ls int/hexdump*
>   ls: cannot access int/hexdump*: No such file or directory
> 
> So I don't really understand "int.hexdump".

You can't just import functions from any random place. You can only import
them from where they actually exist.

from math import path  # fails, because there is no math.path

from os import path  # succeeds, because os.path does exist


You can't import int.hexdump if you haven't written a file int/hexdump.py.



> I have these function definitions:
> 
>   codec/objects.py:47:def hexdump (s, l = None):
>   int/struct_phy.py:26:def hexdump (s, l = None):
> 
> both in modules.
> 
> It fails to load:
> 
>   from struct_phy import hexdump
> 
> or:
> 
>     from int.struct_phy import hexdump
> ImportError: cannot import name hexdump


At this point, I'm so confused by your setup that I'm about to give up and
go to bed. 



-- 
Steven




More information about the Python-list mailing list