Python includes, module scope issue

I'm working on my first significant Python project and I'm having trouble with scope issues and executing code in included files. Previously my experience is with PHP.

What I would like to do is have one single file that sets up a number of configuration variables, which would then be used throughout the code. Also, I want to make certain functions and classes available globally. For example, the main file would include a single other file, and that file would load a bunch of commonly used functions (each in its own file) and a configuration file. Within those loaded files, I also want to be able to access the functions and configuration variables. What I don't want to do, is to have to put the entire routine at the beginning of each (included) file to include all of the rest. Also, these included files are in various sub-directories, which is making it much harder to import them (especially if I have to re-import in every single file).

Anyway I'm looking for general advice on the best way to structure the code to achieve what I want.

Thanks!


Asked by: Roman653 | Posted: 30-11-2021






Answer 1

In python, it is a common practice to have a bunch of modules that implement various functions and then have one single module that is the point-of-access to all the functions. This is basically the facade pattern.

An example: say you're writing a package foo, which includes the bar, baz, and moo modules.

~/project/foo
~/project/foo/__init__.py
~/project/foo/bar.py
~/project/foo/baz.py
~/project/foo/moo.py
~/project/foo/config.py

What you would usually do is write __init__.py like this:

from foo.bar import func1, func2
from foo.baz import func3, constant1
from foo.moo import func1 as moofunc1
from foo.config import *

Now, when you want to use the functions you just do

import foo
foo.func1()
print foo.constant1
# assuming config defines a config1 variable
print foo.config1

If you wanted, you could arrange your code so that you only need to write

import foo

At the top of every module, and then access everything through foo (which you should probably name "globals" or something to that effect). If you don't like namespaces, you could even do

from foo import *

and have everything as global, but this is really not recommended. Remember: namespaces are one honking great idea!

Answered by: Ada160 | Posted: 01-01-2022



Answer 2

This is a two-step process:

  1. In your module globals.py import the items from wherever.
  2. In all of your other modules, do "from globals import *"

This brings all of those names into the current module's namespace.

Now, having told you how to do this, let me suggest that you don't. First of all, you are loading up the local namespace with a bunch of "magically defined" entities. This violates precept 2 of the Zen of Python, "Explicit is better than implicit." Instead of "from foo import *", try using "import foo" and then saying "foo.some_value". If you want to use the shorter names, use "from foo import mumble, snort". Either of these methods directly exposes the actual use of the module foo.py. Using the globals.py method is just a little too magic. The primary exception to this is in an __init__.py where you are hiding some internal aspects of a package.

Globals are also semi-evil in that it can be very difficult to figure out who is modifying (or corrupting) them. If you have well-defined routines for getting/setting globals, then debugging them can be much simpler.

I know that PHP has this "everything is one, big, happy namespace" concept, but it's really just an artifact of poor language design.

Answered by: Marcus538 | Posted: 01-01-2022



Answer 3

As far as I know program-wide global variables/functions/classes/etc. does not exist in Python, everything is "confined" in some module (namespace). So if you want some functions or classes to be used in many parts of your code one solution is creating some modules like: "globFunCl" (defining/importing from elsewhere everything you want to be "global") and "config" (containing configuration variables) and importing those everywhere you need them. If you don't like idea of using nested namespaces you can use:

from globFunCl import *

This way you'll "hide" namespaces (making names look like "globals").

I'm not sure what you mean by not wanting to "put the entire routine at the beginning of each (included) file to include all of the rest", I'm afraid you can't really escape from this. Check out the Python Packages though, they should make it easier for you.

Answered by: Emma427 | Posted: 01-01-2022



Answer 4

This depends a bit on how you want to package things up. You can either think in terms of files or modules. The latter is "more pythonic", and enables you to decide exactly which items (and they can be anything with a name: classes, functions, variables, etc.) you want to make visible.

The basic rule is that for any file or module you import, anything directly in its namespace can be accessed. So if myfile.py contains definitions def myfun(...): and class myclass(...) as well as myvar = ... then you can access them from another file by

import myfile
y = myfile.myfun(...)
x = myfile.myvar

or

from myfile import myfun, myvar, myclass

Crucially, anything at the top level of myfile is accessible, including imports. So if myfile contains from foo import bar, then myfile.bar is also available.

Answered by: Joyce553 | Posted: 01-01-2022



Similar questions

Large Python Includes

I have a file that I want to include in Python but the included file is fairly long and it'd be much neater to be able to split them into several files but then I have to use several include statements. Is there some way to group together several files and include them all at once?


python - Put bar at the end of every line that includes foo

I have a list with a large number of lines, each taking the subject-verb-object form, eg: Jane likes Fred Chris dislikes Joe Nate knows Jill To plot a network graph that expresses the different relationships between the nodes in directed color-coded edges, I will need to replace the verb with an arrow and place a color code at the end of each line, thus, somewhat simplified: Jane -> Fred r...


python - How to check if phone number entered by user includes country code?

Is there an easy way to check whether a phone number entered by the user includes country code and to validate that the number is correct? I don't use any specific formats, the number itself must be only digits, no ('s, -'s and the like. Is such validation possible without asking user for a country? The trick is that I want to work with all numbers world-wide. I guess it can't be done with regex (googled a bit and...


python - PyCUDA: C/C++ includes?

Something that isn't really mentioned anywhere (at least that I can see) is what library functions are exposed to inline CUDA kernels. Specifically I'm doing small / stupid matrix multiplications that don't deserve to be individually offloaded to the GPU but am offloading a larger section of the algorithm which includes this multiplication. Noone ever liked using their own linalg functions since someone has always ...


python - Something wrong without any error - Includes Tkinter

I'm not getting any error but the code doesn't do what I want so there must be somewhere in the code where I have made a mistake. What I want to do is if the words match then the words must be a pair and the two chosen cells should remain "self.hidden = False" and therefore the cells should still show the words behind the two cells. Else if the words doesn't match then the cells should be "self.hidden = True" and the two c...


python - Global includes in Django

I want to create a module containing different utility functions and classes to use across different apps. It's not going to define any models or views. What's the best way to do this?


python - my post method returns (u'') and django saves includes the (u'') string when saving it

This is how I retrieve the post data from the webpage. The person models can be saved but it includes the "(u'')" string. For example if change the firstname to "Alex", it gets the raw value u('Alex') and saves it. def submit_e(req, person_id=None): if(req.POST): try: person_id = req.POST['driver'] person = Person.objects.get(pk=person_id) ...


python - How do I return a string that includes new lines?

I have a question that requires I use return and I do not know how to return on multiple lines. I need to be able to get an output that looks like this Dear so and so, kjhagjkahgsdhgl;dslhglk jkasdhgjkdshkglhds;g kjdghksadjglkdjslkg kjgahkjsdhlgkdsjg;lsd where the gibberish are strings that I have


python - Celery beat queue includes obsolete tasks

I'm using periodic celery tasks with Django. I used to have the following task in my app/tasks.py file: @periodic_task(run_every=timedelta(minutes=2)) def stuff(): ... But now this task has been removed from my app/tasks.py file. However, I keep seeing call to this task in my celery logs: [2013-05-21 07:08:37,963: ERROR/MainProcess] Received unregistered task of type u'ap...


Python: mplot3d, plot a 3D solid shape that includes dots inside

I am trying to plot in python using mplot3d, a solid shape that includes inside, a group of dots that are represented in a 3d space. Perhaps the images will clarify my question. I was thinking of a sphere but also an irregular solid could work. If it is a sphe...






Still can't find your answer? Check out these communities...



PySlackers | Full Stack Python | NHS Python | Pythonist Cafe | Hacker Earth | Discord Python



top