Problem importing modules and functions in Python - python

I have two files: in one of them (named myrandom) I have defined a function called spinner that would choose a random number from 1 to 6 and would return its value. In the second file, named main, I have imported the first one (as a module) and have also called the spinner function.
This is the code of the file myrandom:
def spinner():
import random
val = random.choice([1, 2, 3, 4, 5, 6])
return val
And this is the code of main:
import myrandom
x = spinner()
print(x)
My problem is that when I run main, I get the following error message: "NameError: name spinner() is not defined". I don't know why I'm getting this error, since I have other files and modules with similar characteristics that run without problems.
Any idea?

You need to use it like:
import myrandom
x = myrandom.spinner()
Or import directly:
from myrandom import spinner
x = spinner()
Or use star import:
from myrandom import *
x = spinner()

You should import it either like this:
import myrandom
x = myrandom.spinner()
or like this:
from myrandom import spinner
x = spinner()
or like this:
from myrandom import *
x = spinner()
An explanation of the different ways of importing can be found here: Importing modules in Python - best practice

Related

How to get "name" from module when using "import module as name"

I can't seem to find where the actual name that a module has been bound to is stored. For example:
import re as my_re
print my_re.__name__ # Output is "re," not "my_re"
I would like to be able to get the name that I imported the module as rather than the actual name of the module.
My use case is that I have a function that takes a function object as an argument and needs to be able to determine what name it is bound to. Here is a more thorough example:
import module as my_module
def my_func(in_func):
print in_func.__bound-name__ # Or something to this effect
my_func(my_module.function1) # Should print "my_module.function1"
I would pass the module name as string and then use globals() to fetch the module for use within the function. Suppose you pass 'np' to the function, then globals()['np'] will return the function.
In [22]: import numpy as np
In [23]: def demo(A):
...: a = globals()[A]
...: print(a.array([i for i in range(10)]))
...:
In [24]: demo('np')
[0 1 2 3 4 5 6 7 8 9]
There is no way to do exactly what you want because string my_re is not stored anywhere, it is only a name of a variable. PEP221 which proposed the syntax for import ... as statement explains that the following lines are equal:
import re as my_re
and
import re
my_re = re
del re

How to get a variable from an external function

How, if possible, would I be able to bring in a variable from an external function. Take this code
# HttpThing.py
import requests
def httpThing(someurl):
x = requests.get(someurl)
In another file I have
from httpThing.py import httpThing
httpThing(www.url.com)
print(x)
How would I be able to get the last print function to print the response to the query.
you return that value from the function like this:
# HttpThing.py
import requests
def httpThing(someurl):
x = requests.get(someurl)
return x
then use it like this:
from httpThing import httpThing
x = httpThing(www.url.com)
print(x)
NOTE: the variable that you return dosen't have to be same as the variable where you call that function for printing it. it could be named anything.

Modules as function arguments

I have a python script that starts with importing a python module that contains data. A very simplified example is given below:
my_data1.py
bar = 10
baz = [1, 5, 7]
...
my_func.py
from my_data1 import *
def foo():
'''
function that uses the things defined in data (scalar, list, dicts, etc.)
in my_data
'''
return [bar] + baz
This works great for one set of data; however, I have my_data1.py, ..., my_data36.py.
my_data36.py
bar = 31
baz = [-1, 58, 8]
...
that I want to import and then run foo() with that data. I wanted to do something like this:
def foo(my_data):
from my_data import *
results = []
for i in range(1,37):
results.append(foo('my_data{}'.format(i)))
This doesn't work. Ideas?
Use __import__. It takes a string as parameter identifying the module to be imported, and returns the module, which then you can pass as an argument to your functions.
def processDataSet (module):
print (module.baz)
for m in ['data1.py', 'data2.py', 'data69.py']:
processDataSet (__import__ (m) )
"from module import * is invalid inside function definitions." from http://docs.python.org/2/howto/doanddont.html#inside-function-definitions

Correctly return variable from python module

I'm sure this is absurdly simple but I have been unable to get it working.
I want to return the value of x from within my function test in the module 'user_module' to my 'main_program'
file: user_module
def test ():
x =5
return x
file: main_program
import user_module
user_module.test()
print x
However the above code does not work :( I get the following error
NameError: name 'x' is not defined
In your module x is defined within the function test.
That means that it is only availavle inside the scope of that function.
Even if you would try to access x from within the module you would get a name error because x was not globally defined in that module.
This would not work:
file: user_module
def test ():
x =5
return x
print x
Produces a NameError.
(that does not mean the general solution is making everything globally available...)
To solve your problem you could create a variable named x.
You would have to change your code like this:
import user_module
x = user_module.test()
print x
Or instead of printing x you could just print the result of test().
print user_module.test()
This is because x is defined in a function, which means it is in the function's scope, not in the module's. But your function is returning it — which is good:). So use one of these solutions to get x:
1.
import user_module
print user_module.test()
2.
If you want to pass x from one module to another, then your user_module will look like this:
x = 5
and in the main script you do this:
import user_module
print user_module.x
3.
Or you can do this in your user_module:
def test():
x = 5
return x
x = test()
Now in your main script you do this:
import user_module
print user_module.x

Python "import" performance query

Well, this query struck my mind when someone pointed out to me that importing a package using import package gives more code readability. Is this actually true? I mean when using this statement as compared to from package import x, y, z, isn't there any overhead of importing the entire package?
I don't expect any performance difference. Whole package will be loaded anyway.
For example:
# load dirname() function from os.path module
>>> from os.path import dirname
#the os.path.basename() was not imported
>>> basename('/foo/bar.txt')
NameError: name 'basename' is not defined
# however, basename() is already available anyway:
dirname.__globals__['basename']('/foo/bar.txt')
Using the point notation is always less performant than importing a function directly and calling it, because the function does have to be searched in the modules dictionary. This counts for every getattr operation.
For example when appending items to a list:
lst = []
for i in xrange(5000):
lst.append(i ** .5 * 2)
This is faster:
lst = []
append = lst.append
for i in xrange(5000):
append(i ** .5 * 2)
This can make a real heavy difference.
>>> def bad():
... lst = []
... for i in xrange(500):
... lst.append(i ** .5 * 2)
>>> def good():
... lst = []
... append = lst.append
... for i in xrange(500):
... append(i ** .5 * 2)
>>> from timeit import timeit
>>> timeit("bad()", "from __main__ import bad", number = 1000)
0.175249130875
>>> timeit("good()", "from __main__ import good", number = 1000)
0.146750989286
The performance will be same either way. The entire module is compiled, if needed, and the code executed, the first time you import a module, no matter how you import it.
Which is more readable
from os.path import split, join
then a bunch of split and join calls that would accidentally be read as the string methods of the same name, or
import os.path
then referencing them as os.path.split and os.path.join? Here, it's clear they're methods dealing with paths.
Either way, you have to actually load the whole module. Otherwise, things that you imported that depended on other things in the module you didn't import wouldn't work.

Categories

Resources