Globals between files in python - python

I am making a game, a simple 2d RPG in python, using pygame. I'm now adding zooming in and out using the scrollwheel. I have a file called stuff.py along with my main.py file and a bunch of other files (player.py, enemy1.py, enemySpawner.py, chest.py etc.). In the stuff.py file, I have an int called sizeofEverything, and everything is scaled ( square shape) to sizeofEverything. Main.py is the only file that is executed, so In main.py, I detect if the scrollWheel has been interacted with, and if it has been, I want to change sizeofEverything. The problem is, that would just change the local copy of sizeofEverything that I imported into main.py .I need some way to change it, from the main.py file, so that it also updates in all the other files (enemy1.py, player.py etc. ) How would this be done?

I'd recommend rethinking how the variables are defined and how you change them. For example, instead of trying to change a variable in another file, perhaps you can pass a variable to a function in another file, and store all the variables in the main script. Global variables tend to be frowned upon, but only because they make things pretty messy overall.

Create a config module specifically which defines your global variables e.g. config.py
Import this module into each of the files which need access to the global.

Related

Can a Python module be multiple files?

For years, I've known that the very definition of a Python module is as a separate file. In fact, even the official documentation states that "a module is a file containing Python definitions and statements". Yet, this online tutorial from people who seem pretty knowledgeable states that "a module usually corresponds to a single file". Where does the "usually" come from? Can a Python module consist of multiple files?
Not really.
Don't read too much into the phrasing of one short throwaway sentence, in a much larger blog post that concerns packaging and packages, both of which are by nature multi-file.
Imports do not make modules multifile
By the logic that modules are multifile because of imports... almost any python module is multifile. Unless the imports are from the subtree, which has no real discernible difference to code using the module. That notion of subtree imports, btw, is relevant... to Python packages.
__module__, the attribute found on classes and functions, also maps to one file, as determined by import path.
The usefulness of expanding the definition of modules that way seems… limited, and risks confusion. Let imports be imports ans modules be modules (i.e. files).
But that's like, my personal opinion.
Let's go all language lawyer on it
And refer to the Python tutorial. I figure they will be talking about modules at some point and will be much more careful in their wording than a blog post which was primarily concerned about another subject.
6. Modules
To support this, Python has a way to put definitions in a file and use them in a script or in an interactive instance of the interpreter. Such a file is called a module; definitions from a module can be imported into other modules or into the main module (the collection of variables that you have access to in a script executed at the top level and in calculator mode).
A module is a file containing Python definitions and statements. The file name is the module name with the suffix .py appended. Within a module, the module’s name (as a string) is available as the value of the global variable name.
p.s. OK, what about calling it a file, instead of a module, then?
That supposes that you store Python code in a file system. But you could have an exotic environment that stores it in a database instead (or embeds it in a larger C/Rust executable?). So, module, seems better understood as a "contiguous chunk of Python code". Usually that's a file, but having a separate term allows for flexibility, without changing anything to the core concepts.
Yup, a python module can include more than one file. Basically what you would do is get a file for the main code of the module you are writing, and in that main file include some other tools you can use.
For example, you can have the file my_splitter_module.py, in which you have... say a function that gets a list of integers and split it in half creating two lists. Now say you wanna multiply all the numbers that are in the first half between each other ([1, 2, 3] -> 1 * 2 * 3), but with the other half sum them ([1, 2, 3] -> 1 + 2 + 3). Now say you don't want to make the code messy and so you decide to make another two functions, one that gets a list and multiply its items, and another that sum them.
Of course, you could make the two functions in the same my_splitter_module.py file, but in other situations when you have big files with big classes etc, you would like to make a file like multiply_list.py and sum_list.py, and then importing them to the my_splitter_module.py
At the end, you would import my_splitter_module.py to your main.py file, and while doing this, you would also be importing multiply_list.py and sum_list.py files.
Yes, sure.
If you create a folder named mylib in your PATH or in the same directory as your script, it allows you to use import mylib.
Make sure to put __init__.py in the folder and in that imoprt everything from other files because the variables, functions, etc. import just from the __init__.py.
For example:
project -+- lib -+- __init__.py
| +- bar.py
| +- bar2.py
|
+- foo.py
__init__.py :
from bar import test, random
from bar2 import sample
foo.py :
import lib
print(test)
sample()
Hope it helps.

Declaring variables for multiple scripts and best practices

What is the best way to put variables in python for multiple scripts?
I have the following scripts:
main.py: This script to declare common variables for one.py, two.py, and three.py. Also takes input from the user in interactive way and from the defined input file.
config.py: This script has all three scripts configurations inputs like ip-adress, ports details. etc.
one.py: I have written this script with class and it take inputs from main.py and config.py.
two.py: I have written this script with class and it take inputs from main.py and config.py.
three.py: I have written this script with class and it take inputs from main.py and config.py.
run.py: This script loads class objects for the one.py, two.py, and three.py and calls the functions defined in them.
main.py
list1 = []
a = "common for one.py,two.py and three.py"
one.py
import main
main.list1.append("1")
two.py
import main
main.list1.append("2")
three.py
import main
main.list1.append("3")
Running script:
run.py
import main
import one
import two
import three
# start performing
#call one script functions
#call two script functions
#call three script functions
I need some suggestions from you.
Am I am doing it in right way?
Will my scripts be easy for future maintenance?
Since I am putting variable list1 in main.py. It will first
appending some value in one.py and then two.py is going to access it.
My doubt is two.py is importing main.py in this case it does not
overwrite with empty list value? I have tested it, and it works fine.
But I still want to take your suggestions for best practices.
Yes, I think what you're doing is basically OK. I would rename a couple of the scripts to better indicate their roles: I would rename run.py and make it main.py, and make what you called main.py something like common.py. However, for the sake of discussion, I'll use the script names you have in your question.
You don't have to worry about what's in your main.py reinitializing list1 variable every time it's imported. That's because the results of importing modules are "cached" in sys.modules and the top-level code in them only executes the first time they're imported. If another script imports one of them again, the results of the first time saved in cached version is used. You can think of loaded modules as "singleton" instances of a module class (which in fact they are, see types.ModuleType).
If there's a dependency in your run.py that the modules one, two, and three are imported in a certain order, then I would import them all in your main module, so other scripts don't have to worry about it (the ordering). That way other scripts can just import whichever ones they want to use.
The above is not to say your design couldn't be improved. It looks like you're basically using global variables, which have long been considered a "bad thing" for a number of reasons (see Global Variables Are Bad). To avoid that, the direct use of list1 would need to be replaced with an instance of some new custom class with it's lifetime and access to it handled indirectly via methods defined in the class after explicitly creating an instance of it. This instance would then need to be passed as argument to any function or method that needed use or otherwise do something with or to the instance.
This doesn't look easy to maintain, since the values appended to the list only happen upon calling the import in main. Import them in the wrong order, or forget to import one of them, and you will get unexpected results.
In general, it is fine to share variables between scripts, but the various modules should not edit the values of the shared variables, rather, each module should be solely responsible for the values of its variables.

Make global variables available in multiple modules

I am creating an application consisting of several modules. There is one main.py file which will be the file to run the application. The main.py file will load the configuration file(s) and put them in the 'config'-variable. It will also import the application-module-file (the file which holds the source-code of the application itself, a.k.a. application-class) and start the instance.
I am not very experienced in coding Python, and my biggest question is if I am doing it the right way, by using a main-file to handle all needed stuff (loading configuration-files for example). The problem I am having right now is that I cannot access the 'config'-variable that was defined in the main.py-file from any other module and/or Python-file.
Is it possible to make a global variable for configuration-values exc.? I know in PHP I used to create a singleton object which holds all the specific global arguments. I could also create a global 'ROOT'-variable to hold the full path to the root of the application, which is needed to load/import new files, this is also not possible in Python as far as I know.
I hope someone can help me out of this or send me in the right direction so I can continue working on this project.
The answer seems to be by Matthias:
Use from AppName.modules import settings and then access the data in the module with settings.value. According to PEP-8, the style guide for Python code, wildcard imports should be avoided and would in fact lead to undesirable behaviour in this case.
Thanks you all for the help!

Automatically generate imports, to disentangle one method from a module

I'm working on a huge Python module, like this:
import millions, and, billions, of, modules...
...lots of functions...
def myfunc
...with huge body
...more functions
I'd like to extract myfunc to its own module. However, tracking down all the imports I need is actually pretty tedious. Is there a way to do this automatically using Eclipse? I'm using Eclipse 3.7.0 with Aptana Studio plugin (and hence PyDev). There's an "extract method" refactoring tool, but it doesn't do this.
Ok, maybe this is easier than I thought:
Copy function definition to a new file
Copy the entire imports section to that new file
Unused imports are shown with a wiggly yellow line. Delete them.
Delete the function definition from the original file, replacing it with a call reference.
Now you have unused imports here too, so delete those as per 3.
It's not automatic, but it's relatively straightforward and painless.

Howto import a function with python

I'm developing a Python application for the GAE.
The application consists of a bunch of classes and functions which are at the moment all in the same file main.py.
The application is running without problems.
Now, I want to refactor the application and outsource all the classes. Every class should be in her own file. The files shall be arranged in directories like this:
main.py
/directory1/class1.py
/directory1/class2.py
/directory2/class1.py
My problem is that inside these outsourced classes, I cannot use the functions of main.py.
I tried this inside the class-files.
from main import name_of_function
But the compiler says
from main import name_of_function
ImportError: cannot import name name_of_function
What did I wrong?
The name of the funktion is login. Maybe this causes the problem?
Try moving the extra functions from main.py into a separate file.
main.py
library.py # contains login() and other functions from main
/directory1/class1.py
/directory1/class2.py
/directory2/class1.py
Sometimes it is good to leave classes in same module not separate without purpose if they belong together.
The problem of using function from main is sign that you should refactor one module say common_utils.py out of those functions and separate it from main. You can import that to your modules, which use those. Do not think classes only think whole use case.
If you could give pseudo code of your program's logic, we could check the refactoring better together.

Categories