new import with imports pre-def - python

how to import foo module like this example.
main.py :
import time
from foo import main
return main()
foo.py :
def main()
print 'hello', time.time()
I tried to explain, there are two or more files, I wanted to upload a import already defined by another file without defining in what will be loaded, like my example

Unfortunately that's not how Python works. Names must be available in the scope in which they are used. There is a scope that is always accessible, but modifying it is generally frowned upon since it makes code harder to read and use.

Related

Python global variable in import * [duplicate]

I've run into a bit of a wall importing modules in a Python script. I'll do my best to describe the error, why I run into it, and why I'm tying this particular approach to solve my problem (which I will describe in a second):
Let's suppose I have a module in which I've defined some utility functions/classes, which refer to entities defined in the namespace into which this auxiliary module will be imported (let "a" be such an entity):
module1:
def f():
print a
And then I have the main program, where "a" is defined, into which I want to import those utilities:
import module1
a=3
module1.f()
Executing the program will trigger the following error:
Traceback (most recent call last):
File "Z:\Python\main.py", line 10, in <module>
module1.f()
File "Z:\Python\module1.py", line 3, in f
print a
NameError: global name 'a' is not defined
Similar questions have been asked in the past (two days ago, d'uh) and several solutions have been suggested, however I don't really think these fit my requirements. Here's my particular context:
I'm trying to make a Python program which connects to a MySQL database server and displays/modifies data with a GUI. For cleanliness sake, I've defined the bunch of auxiliary/utility MySQL-related functions in a separate file. However they all have a common variable, which I had originally defined inside the utilities module, and which is the cursor object from MySQLdb module.
I later realised that the cursor object (which is used to communicate with the db server) should be defined in the main module, so that both the main module and anything that is imported into it can access that object.
End result would be something like this:
utilities_module.py:
def utility_1(args):
code which references a variable named "cur"
def utility_n(args):
etcetera
And my main module:
program.py:
import MySQLdb, Tkinter
db=MySQLdb.connect(#blahblah) ; cur=db.cursor() #cur is defined!
from utilities_module import *
And then, as soon as I try to call any of the utilities functions, it triggers the aforementioned "global name not defined" error.
A particular suggestion was to have a "from program import cur" statement in the utilities file, such as this:
utilities_module.py:
from program import cur
#rest of function definitions
program.py:
import Tkinter, MySQLdb
db=MySQLdb.connect(#blahblah) ; cur=db.cursor() #cur is defined!
from utilities_module import *
But that's cyclic import or something like that and, bottom line, it crashes too. So my question is:
How in hell can I make the "cur" object, defined in the main module, visible to those auxiliary functions which are imported into it?
Thanks for your time and my deepest apologies if the solution has been posted elsewhere. I just can't find the answer myself and I've got no more tricks in my book.
Globals in Python are global to a module, not across all modules. (Many people are confused by this, because in, say, C, a global is the same across all implementation files unless you explicitly make it static.)
There are different ways to solve this, depending on your actual use case.
Before even going down this path, ask yourself whether this really needs to be global. Maybe you really want a class, with f as an instance method, rather than just a free function? Then you could do something like this:
import module1
thingy1 = module1.Thingy(a=3)
thingy1.f()
If you really do want a global, but it's just there to be used by module1, set it in that module.
import module1
module1.a=3
module1.f()
On the other hand, if a is shared by a whole lot of modules, put it somewhere else, and have everyone import it:
import shared_stuff
import module1
shared_stuff.a = 3
module1.f()
… and, in module1.py:
import shared_stuff
def f():
print shared_stuff.a
Don't use a from import unless the variable is intended to be a constant. from shared_stuff import a would create a new a variable initialized to whatever shared_stuff.a referred to at the time of the import, and this new a variable would not be affected by assignments to shared_stuff.a.
Or, in the rare case that you really do need it to be truly global everywhere, like a builtin, add it to the builtin module. The exact details differ between Python 2.x and 3.x. In 3.x, it works like this:
import builtins
import module1
builtins.a = 3
module1.f()
As a workaround, you could consider setting environment variables in the outer layer, like this.
main.py:
import os
os.environ['MYVAL'] = str(myintvariable)
mymodule.py:
import os
myval = None
if 'MYVAL' in os.environ:
myval = os.environ['MYVAL']
As an extra precaution, handle the case when MYVAL is not defined inside the module.
This post is just an observation for Python behaviour I encountered. Maybe the advices you read above don't work for you if you made the same thing I did below.
Namely, I have a module which contains global/shared variables (as suggested above):
#sharedstuff.py
globaltimes_randomnode=[]
globalist_randomnode=[]
Then I had the main module which imports the shared stuff with:
import sharedstuff as shared
and some other modules that actually populated these arrays. These are called by the main module. When exiting these other modules I can clearly see that the arrays are populated. But when reading them back in the main module, they were empty. This was rather strange for me (well, I am new to Python). However, when I change the way I import the sharedstuff.py in the main module to:
from globals import *
it worked (the arrays were populated).
Just sayin'
A function uses the globals of the module it's defined in. Instead of setting a = 3, for example, you should be setting module1.a = 3. So, if you want cur available as a global in utilities_module, set utilities_module.cur.
A better solution: don't use globals. Pass the variables you need into the functions that need it, or create a class to bundle all the data together, and pass it when initializing the instance.
The easiest solution to this particular problem would have been to add another function within the module that would have stored the cursor in a variable global to the module. Then all the other functions could use it as well.
module1:
cursor = None
def setCursor(cur):
global cursor
cursor = cur
def method(some, args):
global cursor
do_stuff(cursor, some, args)
main program:
import module1
cursor = get_a_cursor()
module1.setCursor(cursor)
module1.method()
Since globals are module specific, you can add the following function to all imported modules, and then use it to:
Add singular variables (in dictionary format) as globals for those
Transfer your main module globals to it
.
addglobals = lambda x: globals().update(x)
Then all you need to pass on current globals is:
import module
module.addglobals(globals())
Since I haven't seen it in the answers above, I thought I would add my simple workaround, which is just to add a global_dict argument to the function requiring the calling module's globals, and then pass the dict into the function when calling; e.g:
# external_module
def imported_function(global_dict=None):
print(global_dict["a"])
# calling_module
a = 12
from external_module import imported_function
imported_function(global_dict=globals())
>>> 12
The OOP way of doing this would be to make your module a class instead of a set of unbound methods. Then you could use __init__ or a setter method to set the variables from the caller for use in the module methods.
Update
To test the theory, I created a module and put it on pypi. It all worked perfectly.
pip install superglobals
Short answer
This works fine in Python 2 or 3:
import inspect
def superglobals():
_globals = dict(inspect.getmembers(
inspect.stack()[len(inspect.stack()) - 1][0]))["f_globals"]
return _globals
save as superglobals.py and employ in another module thusly:
from superglobals import *
superglobals()['var'] = value
Extended Answer
You can add some extra functions to make things more attractive.
def superglobals():
_globals = dict(inspect.getmembers(
inspect.stack()[len(inspect.stack()) - 1][0]))["f_globals"]
return _globals
def getglobal(key, default=None):
"""
getglobal(key[, default]) -> value
Return the value for key if key is in the global dictionary, else default.
"""
_globals = dict(inspect.getmembers(
inspect.stack()[len(inspect.stack()) - 1][0]))["f_globals"]
return _globals.get(key, default)
def setglobal(key, value):
_globals = superglobals()
_globals[key] = value
def defaultglobal(key, value):
"""
defaultglobal(key, value)
Set the value of global variable `key` if it is not otherwise st
"""
_globals = superglobals()
if key not in _globals:
_globals[key] = value
Then use thusly:
from superglobals import *
setglobal('test', 123)
defaultglobal('test', 456)
assert(getglobal('test') == 123)
Justification
The "python purity league" answers that litter this question are perfectly correct, but in some environments (such as IDAPython) which is basically single threaded with a large globally instantiated API, it just doesn't matter as much.
It's still bad form and a bad practice to encourage, but sometimes it's just easier. Especially when the code you are writing isn't going to have a very long life.

Do packages at the top of a module get imported when we are only calling a function from that module

I have a module foo.py, which I am importing in my file main.py, I have imports at the top of foo.py such as import numpy as np, etc.
Now, if I'm only calling a certain function fun(arg1, arg2, arg3), do the imports at the top of foo.py take place or do I have to add the imports inside the function definition of fun?
Also, does from foo import fun make a difference then import foo in this regard?
File foo.py (to be imported)
import numpy as np
def fun(arg1, arg2, arg3):
x = np.argsort(arg1)
return x
File main.py
import foo
call = fun([2, 34, 0, -1], 4, 5])
Or should I go with this in foo.py?
def fun(arg1, arg2, arg3):
import numpy as np
x = np.argsort(arg1)
return x
No you don't need to import it again inside fun. You can test this out, your code should work even if your import numpy only once at the top of foo.py.
The two ways don't make any difference except that if you import as import foo you have to refer to fun as foo.fun. If you do from foo import fun instead, you can just use fun.
When you import a module, python will execute all the statements in the module file. So, when you import foo, in either of the above two ways, it will run import numpy as np and update the private symbol table for foo. All statements, functions defined inside foo can use symbols in this table without any qualification. In your case, fun will have access to numpy as np.
What happens to numpy import itself is more interesting.
Case 1
from foo import fun
You are only importing fun nothing else. Whatever code in fun will run because of the above reasons, but np itself will be invisible to code in main.
Case 2
import foo
Here you will refer to fun as foo.fun like I said before, but np can also be used as foo.np but this is absolutely not recommended.
It's always best to import modules again if you are going to use them in the current file, don't rely on indirect imports from other files. Since, python caches imports you needn't worry about performance or circular imports.
Read about the import system to understand all this fully.
When the module is loaded for the first time, all the lines in it are run. imports, defs, regular assignments, etc. All these lines initialize a namespace that is the module object. The namespace of foo will have a variable np that points to the loaded numpy module, and a variable fun that points to your function object.
Functions are first class objects in python. In particular, they have a __globals__ (look under "Callable Types" in the linked docs) attribute, which points to the namespace of the module they were defined in. No matter what you do to the reference of foo.fun, the namenp will be available in the function until you delete it from foo itself.
It is not recommended that you import anything inside your function, unless you have good reason to do so, like avoiding a global name. When you import a module, the interpreter will first look into sys.modules. If it is found, the import will not take much longer than a lookup into the global dictionary. However, if the module hasn't been loaded yet, it will be right there and then. You may not want to incur that overhead at an arbitrary point in your program, especially one that may be time-sensitive.
As far as import form, the differences are mostly aesthetic, but they do have practical consequences as well. from foo import fun creates a name fun in your namespace, referring directly to the function object of interest. It contaminates your local namespace with an extra name, but saves you a lookup through foo's namespace dictionary every time you access the function. import foo, on the other hand, keeps everything bundled nicely since you have to call foo.fun, but that requires an extra lookup.
TL;DR
You should put all your imports at the top of your file. It doesn't really matter how you do it.
Don't need to import it again inside function fun().
For further, please check this
Which is a better practice - global import or local import

Getting Variables from Module Which is Being Imported

main:
import fileb
favouritePizza = "pineapple"
fileb.eatPizza
fileb:
from main import favouritePizza
def eatPizza():
print("favouritePizza")
This is what I tried, however, I get no such attribute. I looked at other problems and these wouldn't help.
This is classic example of circular dependency. main imports fileb, while fileb requires main.
Your case is hard (impossible?) to solve even in theory. In reality, python import machinery does even less expected thing — every time you import anything from some module, whole module is read and imported into global(per process) module namespace. Actually, from module import function is just a syntax sugar that gives you ability to not litter your namespace with everything form particular module (from module import *), but behind the scenes, its the almost the same as import module; module.function(...).
From composition/architecture point of view, basic program structure is:
top modules import bottom
bottom modules get parameters from top when being called
You probably want to use favouritePizza variable somehow in fileb, i.e. in eatPizza functions. Good thing to do is to make this function accept parameter, that will be passed from any place that uses it:
# fileb.py
def eatPizza(name):
print(name)
And call it with
# main.py
import fileb
favouritePizza = "pineapple"
fileb.eatPizza(favouritePizza)

Why can't Python's import work like C's #include?

I've literally been trying to understand Python imports for about a year now, and I've all but given up programming in Python because it just seems too obfuscated. I come from a C background, and I assumed that import worked like #include, yet if I try to import something, I invariably get errors.
If I have two files like this:
foo.py:
a = 1
bar.py:
import foo
print foo.a
input()
WHY do I need to reference the module name? Why not just be able to write import foo, print a? What is the point of this confusion? Why not just run the code and have stuff defined for you as if you wrote it in one big file? Why can't it work like C's #include directive where it basically copies and pastes your code? I don't have import problems in C.
To do what you want, you can use (not recommended, read further for explanation):
from foo import *
This will import everything to your current namespace, and you will be able to call print a.
However, the issue with this approach is the following. Consider the case when you have two modules, moduleA and moduleB, each having a function named GetSomeValue().
When you do:
from moduleA import *
from moduleB import *
you have a namespace resolution issue*, because what function are you actually calling with GetSomeValue(), the moduleA.GetSomeValue() or the moduleB.GetSomeValue()?
In addition to this, you can use the Import As feature:
from moduleA import GetSomeValue as AGetSomeValue
from moduleB import GetSomeValue as BGetSomeValue
Or
import moduleA.GetSomeValue as AGetSomeValue
import moduleB.GetSomeValue as BGetSomeValue
This approach resolves the conflict manually.
I am sure you can appreciate from these examples the need for explicit referencing.
* Python has its namespace resolution mechanisms, this is just a simplification for the purpose of the explanation.
Imagine you have your a function in your module which chooses some object from a list:
def choice(somelist):
...
Now imagine further that, either in that function or elsewhere in your module, you are using randint from the random library:
a = randint(1, x)
Therefore we
import random
You suggestion, that this does what is now accessed by from random import *, means that we now have two different functions called choice, as random includes one too. Only one will be accessible, but you have introduced ambiguity as to what choice() actually refers to elsewhere in your code.
This is why it is bad practice to import everything; either import what you need:
from random import randint
...
a = randint(1, x)
or the whole module:
import random
...
a = random.randint(1, x)
This has two benefits:
You minimise the risks of overlapping names (now and in future additions to your imported modules); and
When someone else reads your code, they can easily see where external functions come from.
There are a few good reasons. The module provides a sort of namespace for the objects in it, which allows you to use simple names without fear of collisions -- coming from a C background you have surely seen libraries with long, ugly function names to avoid colliding with anybody else.
Also, modules themselves are also objects. When a module is imported in more than one place in a python program, each actually gets the same reference. That way, changing foo.a changes it for everybody, not just the local module. This is in contrast to C where including a header is basically a copy+paste operation into the source file (obviously you can still share variables, but the mechanism is a bit different).
As mentioned, you can say from foo import * or better from foo import a, but understand that the underlying behavior is actually different, because you are taking a and binding it to your local module.
If you use something often, you can always use the from syntax to import it directly, or you can rename the module to something shorter, for example
import itertools as it
When you do import foo, a new module is created inside the current namespace named foo.
So, to use anything inside foo; you have to address it via the module.
However, if you use from from foo import something, you don't have use to prepend the module name, since it will load something from the module and assign to it the name something. (Not a recommended practice)
import importlib
# works like C's #include, you always call it with include(<path>, __name__)
def include(file, module_name):
spec = importlib.util.spec_from_file_location(module_name, file)
mod = importlib.util.module_from_spec(spec)
# spec.loader.exec_module(mod)
o = spec.loader.get_code(module_name)
exec(o, globals())
For example:
#### file a.py ####
a = 1
#### file b.py ####
b = 2
if __name__ == "__main__":
print("Hi, this is b.py")
#### file main.py ####
# assuming you have `include` in scope
include("a.py", __name__)
print(a)
include("b.py", __name__)
print(b)
the output will be:
1
Hi, this is b.py
2

How to import another external python module?

this is probably a dumb question, but wasnt too sure what else to do.
main.py
import module2
global x
hello="Hello"
x=module2.message()
x.say()
module2.py
class message:
def say():
print hello
When I print hello, i am referring to the hello variable in main.py however this method will return an error. Does anyone know the solution? (i would prefer not to pipe the hello variable into the function)
The only reliable solution is called encapsulation.
So, basically, you could change your code to look like that:
main.py
import module2
global x
hello="Hello"
x=module2.message(hello)
x.say()
module2.py
class message:
def __init__(self, hello):
self.hello = hello
def say():
print self.hello
Plus try to follow coding style of Python - life of you and future developers of your code will be easier.
Multiple options, but do note that one module cannot ever access the calling module directly.
Simply pass hello as a variable (def say(msg): print msg)
Pass all variables in main.py to module2: def say(g): print g['hello'] and say(globals())
Store it somewhere, then extract it when you need it.
Since main.py imports module2.py, you can access the globals defined in moule2 in main.
In your case since module2 is not importing main, so the globals in main is not accessed in module2.
one solution is that defined by #Tadeck
In this particular example, it's totally OK for module2.py to import main.py, there are some gotcha's though.
The most obvious is that main.py is probably being run from the command line, like python main.py, which has the effect of making that file think it's called __main__. You could import that module in module2, but that's sort of unusual; it's called "main.py" and you want to import main. Doing so will cause the module to be imported a second time.
For that to be OK, you have to arrange for importing the file to have no side effects unless it's imported as __main__. A very common idiom in python is to test that condition at the end of a module.
import module2
global x
hello="Hello"
def main():
x=module2.message()
x.say()
if __name__ == '__main__':
main()
And now it's just fine for module2.py to actually import main. On the other hand, importing variables from one module into another gets hard to predict when the imports can be recursive, you may not have that variable yet because the module is already trying to import you. On the other hand, it's always safe to refer to a variable in a module using dotted syntax. So your module2.py should be:
import main
class message:
def say():
print main.hello
which also makes it more obvious just where hello came from.

Categories

Resources