Python 3.x.x one variable spread across multiple .py files - python

This is not a problem with my code, but rather a general question about Python 3.
Say you had a game, which had 4 parts to it, and the first part (main.py) declares a variable
that say, part 2 needs to run itself. Would you be able to declare that variable, then import part2 (That needs the variable to run smoothly) and have the variable carry on from main.py to part2.py after importing part2.py into main.py.

If you want to use the variable once you can do this.
# part2.py
def scream():
print(sound)
# part1.py
import part2
if __name__=="__main__":
part2.sound = "Yoooo"
part2.scream()
#Output:
Yoooo
If you want to be able to change the variable later. You can create a property
Or simply do this:
# part2.py
# gvars is defined later
def scream():
print(gvars.sound)
# part1.py
import part2
class GameVariables:
pass
if __name__=="__main__":
gvars = GameVariables()
part2.gvars = gvars
gvars.sound = "Yooo"
part2.scream()
gvars.sound = "Whaa"
part2.scream()
#output
Yooo
Whaa

here is a simple example you can try out
file1.py
import sys
sys.argv = "Yellow" #probably not a really great Idea but should suffice
from file2 import sys as sys2
print "Imported argv from file2",sys2.argv
print "Same thing? ", sys is sys2
file2.py
import sys
print "My argv f2:",sys.argv

Related

Can't import functions/modules

I'm simply trying to import a function from another script. But despite import running successfully, the functions never enter my local environment.
The paths and files look like this:
project/__main__.py
project/script_a.py
from setup import script_b
x = ABC() # NameError: name 'ABC' is not defined
print(x)
project/setup/__init__.py
project/setup/script_b.py
def ABC():
return "ABC"
I've done this before and the documentation (officials and on here) is quite straightforward but I cannot grasp what I am failing to understand. Is the function running but never entering my environment?
I also tried using...
if __name__ == '__main__':
def ABC():
return "ABC"
...as script_b.
Import the functions inside the module:
from setup.script_b import ABC
Or call the function on the modules name like said in the comments
x = script_b.ABC()

Trying to import a script from other code

I need help to import a script, i did 2 codes, the first is a test with some prints and in the second i try to import them:
Code 1
# I make some print's to try import and show if it works
def first():
print('Test')
class phrase:
def second():
print('Hello')
def third():
print('World')
Code 2
import os
attempt = os.system(r"python C:\Users\Gabri\PycharmProjects\pythonProject\Imagens.py")
# Obviously isn't works =(
attempt.first()
But in code 2, when i did os.system(r"python C:\Users\Gabri\PycharmProjects\pythonProject\Imagens.py") nothing happen.
Someone can help me to import this code? ;-;
1° Code is in C:\Users\Gabri\PycharmProjects\pythonProject
2° in C:\Users\Gabri\PycharmProjects\pythonProject\Prática\Vamove
If you want to keep the files where they are,
You should by able to do this:
import importlib.util
spec = importlib.util.spec_from_file_location(
"name", "C:\\Users\\Gabri\\PycharmProjects\\pythonProject\\Imagens.py")
Imagens = importlib.util.module_from_spec(spec)
spec.loader.exec_module(Imagens)
And then run your commands like this:
Imagens.first()
The easiest is if you put both in the same folder and make that folder a python directory from which you can import your other code as modules. All you need for that is a file in the folder containing a blank __init__.py file. Then you can import it to another code file in the same folder using
from folder_name import Imagens
and you should be able to use Imagens functions like any other module
Ex: Imagens.first()

How to get name of module which tries to import current module(first import of module) in python 3.x?

For an example: there are 2 files
a.py
import b
...
b.py
print('???') # here I want to figure out which module called me
# this module could be imported from different modules/places not even from expected places.
# there is no certain purpose to use such information, just try to find out is it possible.
Question:
Is it possible to figure out name of module which make fisrt import on another module?
PS:
Import patching like here is not an option. b.py could be imported in 3rd party modules separately.
Add the below code in your b.py file then you will get the name of the file which is importing b.
import sys, os
def getCalledModuleName():
try:
sFile = os.path.abspath(sys.modules['__main__'].__file__)
names = sFile.split('\\')
length = len(names)
name = names[length-1]
except:
sFile = sys.executable
names = sFile.split('\\')
length = len(names)
name = names[length - 1]
return name
if __name__=='__main__':
print('Main Function Called')
else:
print('Imported as Module')
print(getCalledModuleName())

Execute python script with same name in different directory

I have the following file structure:
A:
|_ a.py
|_ b.py
B:
|_ a.py
|_ b.py
I want to dynamically execute either A/b.py or B/b.py.
I am using the following code:
from importlib import import_module
path = '/home/username/test/' + module + '/'
if path not in sys.path:
sys.path.append(path)
script = import_module('b', 'Script')
myClass = getattr(script, 'Script')
run = myClass()
Doing this, if I run B/b.py and then A/b.py, it will execute B/b.py instead of A/b.py.
The first script to be run will be executed in the next round.
I need help in making sure the file in the directory I want is run only.
I'm making some assumption on what you want to accomplish here. Even if this is not exactly what you want, it might still push you the right direction: You got two different sub directories, A and B. These contain scripts of identical names a.py and b.py. Based on some condition, your script should call either A/a.py or A/a.py and then maybe B/b.py or B/b.py.
I would set up A and B as actual python modules, that is, create a __init__.py file in both folders. Then have a master-script which somehow determines which module to use..
# root_folder/master.py
import sys
import A
import B
master_script_name = sys.argv[0]
print("I'm the master script : " + str(master_script_name))
def choose_module_A_or_B(arg):
if arg == "A":
print(" You chose module A !")
return A
return B
module = choose_module_A_or_B("A")
module.b.print_locations()
Then,
# root_folder/A/__init__.py
from A import b
and,
# root_folder/A/b.py
import os
import sys
# how to obtain paths and script name:
folder = os.path.dirname(os.path.realpath(__file__))
script = __file__
parent = os.path.abspath(os.path.join(folder, os.pardir))
def print_locations():
print(" --> script : " + str(script))
print(" --> folder : " + str(folder))
print(" --> parent : " + str(parent))
Similarily ..
# root_folder/B/__init__.py
from B import b
and,
# root_folder/B/b.py
import os
import sys
# how to obtain paths and script name:
folder = os.path.dirname(os.path.realpath(__file__))
script = __file__
parent = os.path.abspath(os.path.join(folder, os.pardir))
def print_locations():
print(" --> script : " + str(script))
print(" --> folder : " + str(folder))
print(" --> parent : " + str(parent))
OUTPUT:
$ python master.py
I'm the master script : master.py
You chose module A !
--> script : A\b.py
--> folder : C:\dev\ScriptTesting\py\script_by_name\A
--> parent : C:\dev\ScriptTesting\py\script_by_name
I've read your other, similar question and come up with a solution without any pre-imports. This is (imho) highly un-pythonic, and may by all means be considered a dirty "hack". I highly recommend you to consider my other answer and just properly deal with the imports.
Your problem occurs because you're trashing the namespace, and all it holds dear. When you pollute the namespace with functions/methods with the same signature, there is absolutely no way for the Python-interpreter to distinguish them: it resolves to the one that was first imported.
However, as stated, there is a workaround: There is (currently) no way to unload a python module, but you may reload it, using the imp module. Essentially, it lets you clean up (redefine) the namespace. A complete, working example can be found at my repl.it
# root_folder/main.py
import sys
import imp
from importlib import import_module
def import_script(mod_dir, script):
sys.path.append(mod_dir)
mod = imp.reload(import_module(script, 'Script'))
sys.path.remove(mod_dir)
return mod
# input:
mod_dir = "A"
script = "b"
# import module/script.py
active_mod = import_script(mod_dir, script)
# use module/script.py
mod_name = active_mod.get_mod_name()
print(mod_name) # Prints "A : b.y"
# New input: different module/script.py
mod_dir = "C"
script = "b"
# import module/script.py
active_mod = import_script(mod_dir, script)
# use module/script.py
mod_name = active_mod.get_mod_name()
print(mod_name) # Prints "C : b.y"
when the modules look like below,
# root_folder/A/b.py
def get_mod_name():
return "A : b.py"
Do note that every import is doubled, since everytime you import a module (with possibly a duplicate name), it must also be reloaded to clean up the namespace. It is not enough to just del the module.

import output of command instead of a file - python

I have a very simple script that i wish to test out.
Master script (caller.py):
#!/usr/bin/env python2.7
import test2
test2.printMe()
Function/Module Script (test2.py):
def printMe():
print 'this actually works'
When I run caller.py, it works. Because the test2.py script exists in the same directory from which I'm calling caller.py.
What happens if i need to make the function(s) defined in test2.py available to the caller.py script, through a variable? There are times when the content of the test2.py function script wont always be in a file. Sometimes, it's inside a variable.
So basically, im looking for a way to access the functions that are in a variable just as import would access functions that are in a file.
I wish to be able to do something like this:
from commands import *
def run_command(cmd):
status, text = getstatusoutput(cmd)
print text
run_command('python /tmp/test2.py')
test2.printMe()
Please advise.
Try this:
from sys import path as sys_path
from os import path
def import_module(path_to_py_file):
dir_name, module_name = path.split(path.splitext(path_to_py_file)[0])
sys_path.append(dir_name)
return __import__(module_name)
Now you can do this:
test2 = import_module(r'/tmp/test2.py')
test2.printMe()

Categories

Resources