Python how to include function from another file - python

I have a problem with including a function from another file to main executable script. I have too many functions and my main script became too long and hard to manage. So i've decided to move every function to separate file and than attach/include it. I've read nearly any relative post here to resolve my problem but no luck. Let's see:
main_script.py
==================
from folder.another_file import f_fromanotherfile
class my_data:
MDList=[]
work=my_data()
def afunction():
f_fromanotherfile()
return
and
another_file.py
=====================
#In this file i've put just function code
def f_fromanotherfile():
a=[1,2,3,4]
work.MDList=a
return
And this is the error:
line 11, in f_fromanotherfile
work.MDList=a
NameError: global name 'work' is not defined
Help me please

The scope of 'work' is its module, main_script.py, so you cannot access it from another module. Make 'work' an argument of f_fromanotherfile instead:
In another_file.py:
def f_fromanotherfile(work):
# function body stays the same
In main_module.py:
def afunction():
f_fromanotherfile(work)

because in another_file.py
#In this file i've put just function code
def f_fromanotherfile():
a=[1,2,3,4]
work.MDList=a
return
work is not a global variable.And then doing assignment to it can't work.
u should change ur code to: another_file.py
#In this file i've put just function code
def f_fromanotherfile():
global work
a=[1,2,3,4]
work.MDList=a
return
with the global keyword u can say the variable in so-called global scope and do ur assignment.
PS:kind of like the keyword extern in C?

Related

How to carry variables from imported functions to the main file (Python 3.8.3

I'm making a small game and wanted a settings page function that's in a seperate .py file to keep things more clean and easily editable. I have a global variable called textSpeed (which I use the global keyword to use properly in the function) which I change in this runSettings function, but when I print the variable back in my main file it hasn't changed.
The code in the main file (main.py)
from settings import runSettings
textSpeed = "not set"
runSettings()
print(textSpeed)
The code from the settings fuction file (settings.py)
def runSettings():
global textSpeed
textSpeed = input("select text speed. ")
print(textSpeed)
return textSpeed
textSpeed is a local variable - local to the main module.
You need to reference the variable from settings.
import settings
settings.textSpeed = "not set"
runSettings()
print(settings.textSpeed)
To avoid circular import, I advise you to create a third file if you wish to keep it this way. Let's call it varSpeed.py with the following code:
global textSpeed
textSpeed = "not set"
Then you can import varSpeed from both other files have access to that variable without the circular issue.
The runSettings function already retuns the value it sets as well. Instead of messing with mixing namespaces and importing global variables, just use the returned value in main.py:
textSpeed = runSettings()
the problem is that you are trying to change a variable from a different file, while you have not imported the file. I think the easiest way to handle this is to use a class variable like this:
Main file:
from class_file import MyClass
MyClass.run_settings()
print(MyClass.text_speed)
Settings file:
class MyClass:
text_speed = 'n/a'
#staticmethod
def run_settings():
MyClass.text_speed = input("Select text speed: ")
return MyClass.text_speed

Exec can't access variables in it's parent environment

My friend asked me to build a function that can execute code in a for loop so, I was doing that and I was using exec in the same file I was declaring a variable name, now when I access name from exec, it says NameError: name 'name' is not defined
This thing is in multiple files, one that runs everything, second that includes all functions and one that calls all functions
I have tried to define variables inside exec and sure, it works.
I have tried Accessing variables in functions.py(File that contains every function) file and it works too.
I have tried merging functions.py and test.py(the file that's using exec) and then running it directly through python and it worked
My functions.py file
def forloop(current, maximum, code):
for x in range(current, maximum):
exec(str(code), globals())
My 'test.py'(It's the one where I call functions)
from functions import *
name = 'Ameer'
forloop(1,3,"""
echo(name)
""")
And, I am running it all through another exec in my 'runner.py'
from functions import *
file = open('test.py', "r+")
content = file.read()
exec(content)
Now, it's giving me an error saying NameError: name 'name' is not defined when it is defined. Please can you guys help me with this issue
You need to use the variables from the place where forloop is called.
import inspect
def forloop(current, maximum, code):
frame = inspect.currentframe().f_back
for x in range(current, maximum):
exec(str(code), frame.f_globals, frame.f_locals)

How to use a function containing eval in a file by variable defined at another file from that another file?

Assume, I have created an python file (FirstFile.py) name which contains many functions and other things. One of the function is this (of course, it is simplified):
def func(string):
assert eval(string)
Besides, I have created an python file which imports func() from the file mentioned above. Then this second python file try to execute following process:
from FirstFile import func
amk = 1
func("amk == 1")
When variable "amk" is in the first file, no problem reveals. However, when variable "amk" is in the second file, which is illustrated here, an error reveals:
NameError: name 'amk' is not defined
Would you like to please help me solve this problem?
by default eval executes in the current local/global scope, if you want to specify a different environment you can do something like:
eval("x == 1", {"x":1})
so your function could take an optional environ argument:
def func(string, environ=None):
assert eval(string, environ)
then you can call the function from the other module passing locals() as the environment:
from FirstFile import func
amk = 1
func("amk == 1", locals())
As a side note I'd recommend against evaluating arbitrary code especially if it is coming from another source / module as it could accidentally contain harmful code.

How to run "exec" from the global scope in python

I have a Class. In that class I have a function.
In the function, I have a string variable that holds definitions of several python functions.
I would like from the function to create the functions that are defined in the variable, such that they will be created in the global scope.
After this operation, I would like to be able to call to the new function from the global scope.
For example:
class MyClass:
def create_functions():
functions_to_create = """
def glob1():
return "G1"
def glob2():
return "G2"
"""
# ----> HERE IS THE MISSING PART, LIKE RUNNING exec in the global scope <----
# The following function should work:
def other_function_in_global_scope():
print "glob1: %s, glob2: %s" % (glob1(), glob2())
What should be in the MISSING PART?
Thanks in advance!!!
In python the overrides can monkey-patch anything anytime, but if you just evaluate a bit of code in global namespace, the risk of inadvertent symbol conflict. I'd suggest instead the customer would provide a module and your code would call functions in it if they were defined there (and default implementations otherwise).
That said, documentation suggests:
exec(functions_to_create, globals())
Several things first. What is your reason to creating a function to create other functions? What are you trying to do? There might be a better way. Also here is another way to so called create function that doesn't involve playing around with exec.
>>> def create_functions():
... global glob1
... def glob1():
... return "G1"
...
>>> glob1()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'glob1' is not defined
>>> create_functions()
>>> glob1()
'G1'
>>>
Edit
Injecting source code without exec (THIS IS NOT A GOOD IDEA AT ALL)
Have you customer submit their code then just do a custom import
Customer Submit Code
Save that code as say custom.py
In your code that you want to let the customer inject into do something like the following
import os
if os.path.exists("custom.py"):
import custom
custom.inject()
That way they can give you their code you call inject and they can change things.

Declaration functions in python after call

$ cat declare_funcs.py
#!/usr/bin/python3
def declared_after():
print("good declared after")
declared_after()
$ python3 declare_funcs.py
good declared after
Change call place:
$ cat declare_funcs.py
#!/usr/bin/python3
declared_after()
def declared_after():
print("good declared after")
$ python3 declare_funcs.py
Traceback (most recent call last):
File "declare_funcs.py", line 4, in <module>
declared_after()
NameError: name 'declared_after' is not defined
Is there way to declare only header of function like it was in C/C++?
For example:
#!/usr/bin/python3
def declared_after() # declaration about defined function
declared_after()
def declared_after():
print("good declared after")
I found this Declare function at end of file in Python
Any way there appear another function in the beginning like wrapper, and this wrapper must be called after declaration of wrapped function, this is not an exit. Is there more elegant true-python way?
You can't forward-declare functions in Python. It doesn't make a lot of sense to do so, because Python is dynamically typed. You could do something silly like this, and what would expect it to do?
foo = 3
foo()
def foo():
print "bar"
Obviously, you are trying to __call__ the int object for 3. It's absolutely silly.
You ask if you can forward-declare like in C/C++. Well, you typically don't run C through an interpreter. However, although Python is compiled to bytecode, the python3 program is an interpreter.
Forward declaration in a compiled language makes sense because you are simply establishing a symbol and its type, and the compiler can run through the code several times to make sense of it. When you use an interpreter, however, you typically can't have that luxury, because you would have to run through the rest of the code to find the meaning of that forward declaration, and run through it again after having done that.
You can, of course, do something like this:
foo = lambda: None
foo()
def foo():
print "bar"
But you instantiated foo nonetheless. Everything has to point to an actual, existing object in Python.
This doesn't apply to def or class statements, though. These create a function or class object, but they don't execute the code inside yet. So, you have time to instantiate things inside them before their code runs.
def foo():
print bar()
# calling foo() won't work yet because you haven't defined bar()
def bar():
return "bar"
# now it will work
The difference was that you simply created function objects with the variable names foo and bar representing them respectively. You can now refer to these objects by those variable names.
With regard to the way that Python is typically interpreted (in CPython) you should make sure that you execute no code in your modules unless they are being run as the main program or unless you want them to do something when being imported (a rare, but valid case). You should do the following:
Put code meant to be executed into function and class definitions.
Unless the code only makes sense to be executed in the main program, put it in another module.
Use if __name__ == "__main__": to create a block of code which will only execute if the program is the main program.
In fact, you should do the third in all of your modules. You can simply write this at the bottom of every file which you don't want to be run as a main program:
if __name__ = "__main__":
pass
This prevents anything from happening if the module is imported.
Python doesn't work that way. The def is executed in sequence, top-to-bottom, with the remainder of the file's contents. You cannot call something before it is defined as a callable (e.g. a function), and even if you had a stand-in callable, it would not contain the code you are looking for.
This, of course, doesn't mean the code isn't compiled before execution begins—in fact, it is. But it is when the def is executed that declared_after is actually assigned the code within the def block, and not before.
Any tricks you pull to sort-of achieve your desired effect must have the effect of delaying the call to declared_after() until after it is defined, for example, by enclosing it in another def block that is itself called later.
One thing you can do is enclose everything in a main function:
def main():
declared_after()
def declared_after():
print("good declared after")
main()
However, the point still stands that the function must be defined prior to calling. This only works because main is called AFTER declared_after is defined.
As zigg wrote, Python files are executed in order they are written from top to bottom, so even if you could “declare” the variable before, the actual function body would only get there after the function was called.
The usual way to solve this is to just have a main function where all your standard execution stuff happens:
def main ():
# do stuff
declared_after();
def declared_after():
pass
main()
You can then also combine this with the __name__ == '__main__' idiom to make the function only execute when you are executing the module directly:
def main ():
# do stuff
declared_after();
def declared_after():
pass
if __name__ == '__main__':
main()

Categories

Resources