import from question

I

iu2

Hi all

I've got three files:

file a1.py:
========
the_number = None

file a2.py:
========
import a1

def init():
a1.the_number = 100

file a3.py:
========
from a1 import the_number
import a2

a2.init()
print the_number, type(the_number)

Runninr a3.py I get:
None <type 'NoneType'>

Changing a3.py to:
import a1
import a2

a2.init()
print a1.the_number, type(a1.the_number)

gives:
100 <type 'int'>

Why doesn't it work in the first version of a3.py?

Thanks,
iu2
 
G

George Sakkis

Hi all

I've got three files:

file a1.py:
========
the_number = None

file a2.py:
========
import a1

def init():
a1.the_number = 100

file a3.py:
========
from a1 import the_number
import a2

a2.init()
print the_number, type(the_number)

Runninr a3.py I get:
None <type 'NoneType'>

Changing a3.py to:
import a1
import a2

a2.init()
print a1.the_number, type(a1.the_number)

gives:
100 <type 'int'>

Why doesn't it work in the first version of a3.py?

Thanks,
iu2

Try to guess what the following snippet prints, run it, and see if you
guessed correctly:

s = {'a':None}
x = s['a']
s['a'] = 1
print x

The same mechanism applies to what "from ... import" does.

HTH,
George
 
T

Tobiah

Duncan said:
Think of 'import a2' as being the same as:

a2 = __import__('a2')

and 'from a1 import the_number' as roughly the same as:

the_number = __import__('a1').the_number

In other words think of them as assignments and it should all make sense.

This is a little surprising. So "from mod import *" really copies all of the
scalars into new variables in the local namespace. The same is true with
object pointers I suppose, but this is transparent as all the copies
access the same object.

I always ASSumed that the two forms of import were equivalent, but that
one form did away with the need to be explicit about the namespace: mod.thing
Obviously this is far from the case.
 
B

Ben Finney

Tobiah said:
This is a little surprising. So "from mod import *" really copies
all of the scalars into new variables in the local namespace.

No. Nothing is copied. All the objects (remembering that in Python,
*everything* is an object) created by the code in module 'mod' are
given names in the current namespace.
I always ASSumed that the two forms of import were equivalent, but
that one form did away with the need to be explicit about the
namespace: mod.thing Obviously this is far from the case.

Yes. In fact the main difference is in what namespace the module's
objects are made available.
 
T

Terry Reedy

|
| > This is a little surprising. So "from mod import *" really copies
| > all of the scalars into new variables in the local namespace.

'Scalar' is not a Python term. Neither is 'object pointer' really,
except in respect to the CPython implementation.

| No. Nothing is copied. All the objects (remembering that in Python,
| *everything* is an object) created by the code in module 'mod' are
| given names in the current namespace.

To amplify, 'from mod import *' is, I believe, more or less equivalent to

import mod
for name in mod.__all__
exec "%s = mod.%s" % name,name
del mod

except, of course, that the imported module would not actually be bound to
'mod'
(and need deleting) so that there is no conflict with mod containing the
name 'mod'.
 
T

Tobiah

Ben said:
No. Nothing is copied. All the objects (remembering that in Python,
*everything* is an object) created by the code in module 'mod' are
given names in the current namespace.

Yeah, copied. Just as in:



given b.py:

##########################
thing = 0
##########################

and a.py:

##########################
from b import *
import b

print thing
print b.thing

b.thing = 1
print b.thing
print thing
###########################

0
0
1
0
 
B

Ben Finney

Tobiah said:
Yeah, copied. Just as in:

Again, those aren't copies. There is only one instance of each value,
referenced by multiple names. This is made clearer by using a mutable
value:
>>> a = [1, 2, 3]
>>> b = a
>>> c = b
>>> a = [4, 5, 6]
>>> a, b, c
([4, 5, 6], [1, 2, 3], [1, 2, 3])
([4, 5, 6, 'spam'], [1, 2, 3, 'eggs'], [1, 2, 3, 'eggs'])

The value referenced by 'b' and 'c' is one instance; they don't have
copies of the value. Assignment binds a reference to a value, it
doesn't make a copy.

A "copy" is what's implemented by the standard library 'copy' module,
hence the name.
 
T

Tobiah

Again, those aren't copies. There is only one instance of each value,
referenced by multiple names.


Ok, I get it. I was locally importing a pointer to an integer which is really
the same object as the module name points to, but the assignment changes that.
The confusion for me centered around the fact that a local name can be used
to change values in mutables that are visible from within the module. This
however, does not include assignment to the local name.
 
S

Steven D'Aprano

Ok, I get it. I was locally importing a pointer to an integer

Really? What language were you using? Python doesn't have pointers.

Some *implementations* of Python (e.g. CPython) might have pointers *in
the implementation*, but others (e.g. PyPy, Jython) don't.

which is
really the same object as the module name points to, but the assignment
changes that. The confusion for me centered around the fact that a local
name can be used to change values in mutables that are visible from
within the module. This however, does not include assignment to the
local name.


If you haven't already done so, you should read:

http://effbot.org/zone/python-objects.htm
http://effbot.org/zone/call-by-object.htm


and remember that imports are (more or less) equivalent to assignments.
When you do this:

it is roughly equivalent to:
Alternatively:

is roughly equivalent to:


(and the magic function "get_a_module_from_file_name" is actually called
__import__ with double underscores.)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top