Welcome to the Treehouse Community
Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.
Looking to learn something new?
Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.
Start your free trialLukáš Kriško
3,155 PointsImport understanding
Hello, I thought that I know what keyword import do but when I try this code below I found out that I don't know what import do. I expect that if I import function(new_word) from module test.py
word = "dog"
def new_word():
print(word)
into test2.py
from test import new_word
new_word()
it is the same like writing this into test2.py.
def new_word():
print(word)
new_word()
I try run this code in test2.py and I expected that it will throw an error(word is not defined) because I only import function (not value of word variable) but it runs and writes "dog".Can somebody explain it to me. (I hope that my English was readable.)
3 Answers
Chris Freeman
Treehouse Moderator 68,454 PointsThis is an excellent question! Exactly where does the value for word
come from?
When you import a function from another module, the global variables from that modules are saved as an attribute of the function. 'word' isn't global on import, but is "seen" as a global when new_word
is run:
# Run interactive Python
$ python3
Python 3.4.3 (default, Oct 14 2015, 20:28:29)
[GCC 4.8.4] on linux
Type "help", "copyright", "credits" or "license" for more information.
# show 'word' is not define
>>> 'word' in globals()
False
>>> from test1 import new_word
# 'word' still not defined
>>> 'word' in globals()
False
# inspect function
>>> dir(new_word)
['__annotations__', '__call__', '__class__', '__closure__', '__code__', '__defaults__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__get__', '__getattribute__', '__globals__', '__gt__', '__hash__', '__init__', '__kwdefaults__', '__le__', '__lt__', '__module__', '__name__', '__ne__', '__new__', '__qualname__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__']
# check function captured globals
>>> 'word' in new_word.__globals__
True
>>> new_word.__globals__['word']
'dog'
>>>
# execute in the debugger to see 'word' in captured globals
>>> import pdb
>>> pdb.run('new_word()')
> <string>(1)<module>()->None
(Pdb) 'word' in globals()
False
(Pdb) step
--Call--
> /home/chrisf/devel/Treehouse/questions/lukas-kristo/test1.py(4)new_word()
-> def new_word():
(Pdb) 'word' in globals()
True
(Pdb) step
> /home/chrisf/devel/Treehouse/questions/lukas-kristo/test1.py(5)new_word()
-> print(word)
(Pdb) 'word'
'word'
(Pdb) globals()['word']
'dog'
(Pdb) continue
dog
>>>
Jason Anders
Treehouse Moderator 145,860 PointsHey there,
I'm not 100% sure, but I believe it is printing "dog" because it is hard coded into the variable word
. And in the function you are importing, the function already knows the value of the variable and is printing the passed in variable value, so therefore it will print dog.
:)
Lukáš Kriško
3,155 PointsI'm not 100% sure but I think that i understand how it works.Thanks. I have just one more question. If I made in one file test.py(for example)this class and i import random library into it.
import random
class Fight:
max_damage = 10
min_damage = 5
def damage_rand(self):
damage = random.randint(self.min_damage,self.max_damage)
return damage
And then I import Fight class into this file(test2.py)
from test import Fight
class Warrior(Fight):
name="Blabla"
warrior1 = Warrior()
print(warrior1.damage_rand())
When is executed last command (print(warrior1.damage_rand())) it can use randint from random library although I do not import it into test2.py.
Here is my explanation: When I import class Fight from test.py into test2.py class Fight takes functions from random library(because I import random library into test.py) and this functions becomes attributes of this class(or something like that).So when I use this function imported from Fight class
def damage_rand(self):
damage = random.randint(self.min_damage,self.max_damage)
return damage
in test2.py it can use function from random library although random library wasn't imported into test2.py.
Is it correct or wrong explanation?
Chris Freeman
Treehouse Moderator 68,454 PointsYou are correct. If in test2.py you tried to add new code using randint
it would fail without an import:
>>> warrior1.damage_rand()
8
>>> warrior1.damage_rand()
10
>>> random.randint(0, 10)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'random' is not defined
>>> import random
>>> random.randint(0, 10)
0
>>> random.randint(0, 10)
6