I have two main python scripts in my project:
sftpConnector.py and fileIterator.py
sftpConnector.py establishes connection to an SFTP server and downloads some file, it however does not call any other script. It has only function: establisher()
While, fileiterator.py also has one function iterator() it calls two other scripts: folderGenerator.py and dataProcessor.py()
When independently called, both the scripts, sftpConnector.py and fileIterator.py execute properly without any issues, however, when I try to create a main.py file to call these two scripts one after the other, it does not work.
The main.py looks like this:
import sftpConnector
import fileIterator
if __name__ == 'main':
folder_name = input('File name:\n')
print('folder_name')
sftpConnector.establisher(folder_name)
fileIterator.iterator(folder_name)
This main.py file runs the first script and function, sftpConnector.establisher(folder_name) however it does not even go inside the second script. I am not sure what's going on here.
Also, not sure if this will help, but neither of the script are returning anything.
Your run guard should be
if __name__ == "__main__":
That’s how to ensure that your code only runs if run as a module (versus being imported). You accidentally checked for the wrong name (“main”) and I’m guessing that’s why the code in your if block isn’t running. It’s an easy mistake to make as it’s easy to assume that __name__ refers to the name of your file when you run your script directly, but it doesn’t; it refers to the environment where the toplevel code is run. The line if __name__ == '__main__': is asking the question: “Is this script the toplevel one?”
Related
I am trying to run a script that pulls data from online sources and then emails it to me at specified times. The idea is to run this script from another Python script which uses APScheduler to run the initial script. The reason I wanted to create 2 scripts is because I want to use something like cx_freeze to make an exe file out of the 2nd script which will run in the background of my pc so as not to have to have my IDE open all the time.
My code in the 2nd script looks as follows:
from apscheduler.schedulers.blocking import BlockingScheduler
import initial_script
import os
if __name__ == '__main__':
scheduler = BlockingScheduler()
scheduler.add_job(initial_script, trigger='cron', day_of_week='mon-fri', hour='18', minute='30')
print('Press Ctrl+{0} to exit'.format('Break' if os.name == 'nt' else 'C'))
try:
scheduler.start()
except (KeyboardInterrupt, SystemExit):
pass
The 'initial_script' is the main python file that actually provides the information I need. The APScheduler code I mostly used from the Github repo here and then I consulted this link to better understand the purpose for using the __name__ = '__main__' code (which I have a feeling is the problem). In the 'initial_script' file I have not used __name__ = '__main__' anywhere.
I have made sure that both files are saved as .py formats - initially I attempted to run the scripts from .py into jupyter notebooks .ipynb but that caused more issues.
The code from the 'initial_script' does run as I am receiving the email when I run it from the 2nd script but the scheduler/trigger gives me an error and does not run.
The error I get now is as follows: TypeError: func must be a callable or a textual reference to one
Please can you assist in explaining what I am doing wrong?
The add_job() method requires that you pass it a callable. You're passing a module and modules cannot be called (you can't do initial_script()). Maybe try passing it a function that is defined in that module?
I have this code:
import sys
def random(size=16):
return open(r"C:\Users\ravishankarv\Documents\Python\key.txt").read(size)
def main():
key = random(13)
print(key)
When I try running the script, there are no errors, but nothing appears to happen. I expected it to print some content from the key file, but nothing is printed.
What is wrong? How do I make the code run?
You've not called your main function at all, so the Python interpreter won't call it for you.
Add this as the last line to just have it called at all times:
main()
Or, if you use the commonly seen:
if __name__ == "__main__":
main()
It will make sure your main method is called only if that module is executed as the starting code by the Python interpreter. More about that here: What does if __name__ == "__main__": do?
If you want to know how to write the best possible 'main' function, Guido van Rossum (the creator of Python) wrote about it here.
Python isn't like other languages where it automatically calls the main() function. All you have done is defined your function.
You have to manually call your main function:
main()
Also, you may commonly see this in some code:
if __name__ == '__main__':
main()
There's no such main method in python, what you have to do is:
if __name__ == '__main__':
main()
Something does happen, it just isn't noticeable
Python runs scripts from top to bottom. def is a statement, and it executes when it is encountered, just like any other statement. However, the effect of this is to create the function (and assign it a name), not to call it. Similarly, import is a statement that loads the other module (and makes its code run top to bottom, with its own global-variable context), and assigns it a name.
When the example code runs, therefore, three things happen:
The code for the sys standard library module runs, and then the name sys in our own module's global variables is bound to that module
A function is created from the code for random, and then the name random is bound to that function
A function is created from the code for main, and then the name main is bound to that function
There is nothing to call the functions, so they aren't called. Since they aren't called, the code inside them isn't run - it's only used to create the functions. Since that code doesn't run, the file isn't read and nothing is printed.
There are no "special" function names
Unlike in some other languages, Python does not care that a function is named main, or anything else. It will not be run automatically.
As the Zen of Python says, "Explicit is better than implicit". If we want a function to be called, we have to call it. The only things that run automatically are the things at top level, because those are the instructions we explicitly gave.
The script starts at the top
In many real-world scripts, you may see a line that says if __name__ == '__main__':. This is not "where the script starts". The script runs top to bottom.
Please read What does if __name__ == "__main__": do? to understand the purpose of such an if statement (short version: it makes sure that part of your top-level code is skipped if someone else imports this file as a module). It is not mandatory, and it does not have any kind of special "signalling" purpose to say where the code starts running. It is just a perfectly normal if statement, that is checking a slightly unusual condition. Nothing requires you to use it in a script (aside from wanting to check what it checks), and nothing prevents you from using it more than once. Nothing prevents you from checking whether __name__ is equal to other values, either (it's just... almost certainly useless).
You're not calling the function. Put main() at the bottom of your code.
There is a python script start_test.py.
There is a second python script siple_test.py.
# pseudo code:
start_test.py --calls--> subprocess(python.exe simple_test.py, args_simple_test[])
The python interpreter for both scripts is the same. So instead of opening a new instance, I want to run simple_test.py directly from start_test.py. I need to preserve the sys.args environment. A nice to have would be to actually enter following code section in simple_test.py:
# file: simple_test.py
if __name__ == '__main__':
some_test_function()
Most important is, that the way should be a universal one, not depending on the content of the simple_test.py.
This setup would provide two benefits:
The call is much less resource intensive
The whole stack of simple_test.py can be debugged with pycharm
So, how do I execute the call of a python script, from a python script, without starting a new subprocess?
"Executing a script" is a somewhat blurry term.
Typically the if __name__== "__main__": part does the argument (sys.argv) decoding and then calls a worker function with explicit parameters. For clarity: It should not do anything else, since this additional work can't be called without creating a new process causing all the overhead you are trying to avoid.
You simply bypass that and call this implementing routine directly.
So you end up with start_test.py containing something like:
from simple_test import worker
# ...
worker(typed_arg1, typed_arg2)
I'm working on a Python project in PyCharm. For one file I would like to test parts of the code using the Python console. Problem is that the code contains a main method (used for debugging and execution) like this:
if __name__ == "__main__":
print("with main")
else:
print("no main")
When I execute that code in the Python Console (using context menu of PyCharm) then the first part of the if will be executed. I was expecting the else-part since I'm not starting the script using a Run-configuration.
Maybe you can help me how to do that.
Create file like not_main_start.py with only one line import main.py (I guess this is your main file). Run then this file. Output should show no main. __name__ would be name __main__ only if you call this file directly. If you use it as module then it will have name of the module.
Sorry for the beginner question, but I can't figure out cProfile (I'm really new to Python)
I can run it via my terminal with:
python -m cProfile myscript.py
But I need to run it on a webserver, so I'd like to put the command within the script it will look at. How would I do this? I've seen stuff using terms like __init__ and __main__ but I dont really understand what those are.
I know this is simple, I'm just still trying to learn everything and I know there's someone who will know this.
Thanks in advance! I appreciate it.
I think you've been seeing ideas like this:
if __name__ == "__main__":
# do something if this script is invoked
# as python scriptname. Otherwise, gets ignored.
What happens is when you call python on a script, that file has an attribute __name__ set to "__main__" if it is the file being directly called by the python executable. Otherwise, (if it is not directly called) it is imported.
Now, you can use this trick on your scripts if you need to, for example, assuming you have:
def somescriptfunc():
# does something
pass
if __name__ == "__main__":
# do something if this script is invoked
# as python scriptname. Otherwise, gets ignored.
import cProfile
cProfile.run('somescriptfunc()')
This changes your script. When imported, its member functions, classes etc can be used as normal. When run from the command-line, it profiles itself.
Is this what you're looking for?
From the comments I've gathered more is perhaps needed, so here goes:
If you're running a script from CGI changes are it is of the form:
# do some stuff to extract the parameters
# do something with the parameters
# return the response.
When I say abstract out, you can do this:
def do_something_with_parameters(param1, param2):
pass
if __name__ = "__main__":
import cProfile
cProfile.run('do_something_with_parameters(param1=\'sometestvalue\')')
Put that file on your python path. When run itself, it will profile the function you want profiling.
Now, for your CGI script, create a script that does:
import {insert name of script from above here}
# do something to determine parameter values
# do something with them *via the function*:
do_something_with_parameters(param1=..., param2=...)
# return something
So your cgi script just becomes a little wrapper for your function (which it is anyway) and your function is now self-testing.
You can then profile the function using made up values on your desktop, away from the production server.
There are probably neater ways to achieve this, but it would work.