Why does Python run my code bottom to top? - python

Assume these 3 files:
charNames.py
a = 'Susan'
b = 'Charlie'
c = 'Jiji'
threenames.py
a = 'dead'
b = 'parrot'
c = 'sketch'
print a,b,c
storytime.py
#!/usr/bin/env python
import charNames
import threenames
print charNames.a
threenames
I run storytime.py (which is also chmod +x) by using ./storytime.py from Terminal, this is the output that I get:
$ ./storytime.py
dead parrot sketch
Susan
$
Why does the result execute print a,b,c from threenames.py before it runs print charNames.a?
From my understanding, Python is a top down programming language, like bash. So should it print "Susan" first, then "dead parrot sketch"?
This is run on OSX, with Python 2.7.5

In Python when you import a file it is executed. That is why you are seeing the output from threenames.py first, because it is executed right after it is imported.
If you want a way to only run code in a file if it is the main file and not an import, you can use this code in threenames.py:
if __name__ == '__main__':
print a, b, c
If you run threenames.py, you will see a,b, and c printed because it is the main file, but when it is imported, it is module, so the print function and any other function calls inside that conditional will not be executed

When you import a file, that file is actually executed. So when you import threenames that file is executed, hence you getting output from within that (the print a,b,c) before you think you called output from it.
You need to avoid printing things out in external modules, instead printing the attributes within like you have with charnames.a.
You should instead use a main() function-like structure:
if __name__ == '__main__':
print a, b, c

Related

How to call the python function from TCL script by passing an argument?

I have a python file sample.py with two functions. So here I want to call the specific python function from tcl script, also I want to passing an argument to that python function. Could you please share your ideas. I don't know whether it is possible. Your answers will be more helpful for us.
sample.py
def f1(a,b,c):
x = a + b + c
retun x
def f2(a,b):
x = a + b
return x
Looks like you need to launch a python interpreter, read the sample script, invoke the function, and print the result. Tcl can then capture the printed output:
$ tclsh
% set a 3
3
% set b 5
5
% set result [exec python -c "import sample; print sample.f2($a,$b)"]
8
With tclpython, you can do an in-process evaluation:
package require tclpython
set a 3
set b 5
# Make a Python system within this process
set py [python::interp new]
# Run some code that doesn't return anything
$py exec {import sample}
# Run some code that does return something; note that we substitute a and b
# *before* sending to Python
set result [$py eval "sample.f2($a,$b)"]
puts "result = $result"
# Dispose of the interpreter now that we're done
python::interp delete $py
The main thing to watch out for is the quoting of complex values being passed into the Python code, as you're using evaluation. It's trivial for numbers, and requires care with quoting for strings.

Why is my Python function not being executed? [duplicate]

This question already has answers here:
Why doesn't the main() function run when I start a Python script? Where does the script start running (what is its entry point)?
(5 answers)
Closed 6 years ago.
I have written a script that is pretty temperamental with indentation, so I decided to make functions. I'm pretty new to Python and now that I've created these functions, nothing works!
def main():
wiki_scrape()
all_csv()
wiki_set = scraped_set('locations.csv')
country_set = all_set('all.csv')
print wiki_set
I'm just wondering if this is the correct way to call functions from the main() function? I've been debating if an indentation issue is occurring within the called functions. Python seems to be very reliant on proper indentations even though it doesn't come up with an error!
Full Code - http://pastebin.com/gJGdHLgr
It sounds like you need to do this:
def main():
wiki_scrape()
all_csv()
wiki_set = scraped_set('locations.csv')
country_set = all_set('all.csv')
print wiki_set
main() # This calls your main function
Even better:
def main():
wiki_scrape()
all_csv()
wiki_set = scraped_set('locations.csv')
country_set = all_set('all.csv')
print wiki_set
if __name__ == '__main__':
main() # This calls your main function
Then run it from the command line like this:
python file_name.py
The built-in variable __name__ is the current contextual namespace. If you run a script from the command line, it will be equivalent to '__main__'. If you run/import the .py file as a module from somewhere else, including from inside the interpreter, the namespace (inside of the context of the module) will be the .py file name, or the package name if it is part of a package. For example:
## File my_file.py ##
print('__name__ is {0}'.format(__name__))
if __name__ = '__main__':
print("Hello, World!")
If you do this from command line:
python my_file.py
You will get:
__name__ is __main__
Hello, World!
If you import it from the interpreter, however, you can see that __name__ is not __main__:
>>> from my_file import *
>>> __name__ is my_file
Python doesn't call any functions on starting unless explicitly asked to (including main).
Instead Python names the files being run, with the main file being run called __main__.
If you want to simply call the main function you can use Rick's answer.
However in Python best practice it is better to do the following:
if __name__ == '__main__':
wiki_scrape()
all_csv()
wiki_set = scraped_set('locations.csv')
country_set = all_set('all.csv')
print wiki_set
This ensures that if you are running this Python file as the main file (the file you click on, or run from the command line then these functions will be run.
If this is instead used as an imported module, you can still use the functions in the script importing the module, but they will not be called automatically and thus won't interfere with the calling script.

Is this a name-value binding issue during module load time by python interpreter?

I wrote a small program in sample.py file,
a=6
def f1():
a=3
return f2()
#def f2(): commented intentionally
# b = a*a
# return b
and loaded as __main__ module using command
>>>python -i sample.py
But i see that interpreter does not check the binding of f2 during loading of module.
Interpreter only realises that f2 name is not binded to its value when i call
>>>f1()
Another example, where interpreter checks the binding of name big1 , while loading the file as __main__ module using command >>>python -i sample.py throws an error saying big1 is not defined
big, small = 3, -4
while big > 2 or small < -2:
big, small = -small - 1, -big + 1
print(big1)
My question is:
1)
Why python interpreter does not take an effort to check whether all names are bind during loading of sample.py file as __main__ module and defer to using that name f1()?
2) Do you think large projects will create complexity, Because the test cases written must make sure each name is used for testing before it goes for production?
Consider this example:
def f1():
name = raw_input()
exec "def {}(): print 'I am a function'".format(name)
f2()
If a user enters "f2" when prompted, then f2() will execute correctly, but not otherwise.
This is a perfectly legal python program, and the line f2() may or may not execute correctly, dependent completely on user input. So python cannot determine at module load time whether execution of this code will result in a name error or not.
Addressing some additional confusion:
It might seem that python does sometimes do static name-checking. Ie, if we have file1.py:
def foo():
print x1
and you do python file1.py, no error will be printed. The function foo has been defined, but not run. We could also do python -i file1.py, which will open up an interpreter. If in the interpreter we then type foo(), now the code will run, and we'll get the lookup error for x1.
Consider a second file file2.py:
print x1
Here, there is no function being defined. We're simply running a print statement at the top-level. Doing python file2.py will cause a lookup error for x1, since running file2.py constitutes actually running that print statement, as opposed to only defining a function that would run the print statement when called.
So it's not that python sometimes does static name-checking -- python will only throw a name error when code involving that name is actually run. It's just that when code gets run depends on where it is (in a function vs being top-level).

Importing a py file within itself

This is test.py:
import sys
a = 50
b = [1,2]
def change():
print "Here 1"
import test
print "Here 2"
test.a = -1
test.b = [0,1]
return
def main():
print "Here 3"
change()
print "Here 4"
print a, b
if 1:
main()
The above python code when ran on system generates the following output:
Here 3
Here 1
Here 3
Here 1
Here 2
Here 4
-1 [0, 1]
Here 2
Here 4
50 [1, 2]
What I am confused why is not there an infinite loop of "Here 1 \n Here 3" outputs. How can the print a, b outputs can be justified?
When you run the file as a script, it is not considered to be the test module. It is considered to be the __main__ module.
When execution hits import test, a second execution of the file starts, where the module is considered to be test.
When execution hits import test again, Python recognizes that it's already importing test and does not reexecute the module. Instead, it merely loads the half-initialized test module object into the current namespace and continues on. Python's optimistic assumption is that you've written the code so that the contents of test won't be needed until the import finishes.
When execution hits the assignments to test.a and test.b, that affects the test module, but not __main__, despite the fact that they came from the same file. Thus, the print a, b from the imported module reflects the new values, while the print a, b from __main__ reflects the initial values.
A file can only be imported once. The 'import test' line succeeds the first time it is encountered. When it is encountered a second time, the interpreter will check that it has already been loaded.
When a program is initially run, it does not count as being 'imported'.
The general flow of this script is as follows:
Main is run, so it prints 'Here 3'
change is called, so it prints 'Here 1'
When importing test, python runs the main function of test
When calling change the second time, python is smart enough to know that test is already imported, so it effectively skips that line.
The imported main finishes running
The original script finishes running.
While user2367112's excellent answer explains why this happens, none of the answers here offer a workaround.
There are two easy ways to achieve the desired behavior.
Rather than importing test, use import __main__ instead. If you assign an alias with import __main__ as test, you won't even have to change any other code.
You can set sys.modules['test'] = sys.modules['__main__'] to tell python "Hey, this module already exists". After this, import test will not re-import the module, thus making your code work as expected. The relevant docs on sys.modules can be found here.

How to run python functions in unix? [duplicate]

This question already has answers here:
What does if __name__ == "__main__": do?
(45 answers)
Closed 5 months ago.
Whenever I tried to run my python script in unix nothing would happen. I'd type something along the lines
$ python script.py
and all that would be returned is
$
Now I know it isn't a problem in my code because that runs fine in idle, so I figured I needed to add something else to my code to be able to run it from the command line. In a google tutorial on python I was introduced to boilerplate code which is tacked onto the end of a function as such
def main():
print ...
etc etc
if __name__ == '__main__':
main()
And if I write a function called main and run it just like that it works fine. However when I named my function something else, anything else, it won't work. E.g.
def merge():
print ..
etc etc
if __name__ == '__merge__':
merge()
That function won't produce any output at all on the command line
Even if I just went and removed the n from the end of word main, each time it occurs in the main function above, it won't work. How does one make python functions run on the command line? and what the heck is up with python only letting functions called main be run?
Thanks!
When you run a python script from the command line, __name__ is always '__main__'.
Try something like:
def merge():
print ..
etc etc
if __name__ == '__main__':
merge()
From the Python interpreter, you have to do something more like:
>>> import script
>>> script.merge()
__name__ == "__main__"
should not be changed, if you run code from the same file you have your functions on
if __name__ == "__main__":
merge()
don't bother about that if only you're importing that module within another file
This link explains you a bith more

Categories

Resources