Quantcast
Channel: Supreme Debugging
Viewing all articles
Browse latest Browse all 13

Python name guard and its importance

$
0
0

Why do we need "__main__" guard in python code?

We all have seen code where we have protected the python code with "__main__" guard. Why do we need this? take a look at below explanation

File - grepinfiles.py

importsysdefgrep(ptrn,txtfl):withopen(txtfl)asf:forlineinf:ifptrninline:yieldline.rstrip('\n')ptrn,txtfl=sys.argv[1],sys.argv[2]formatchlineingrep(ptrn,txtfl):print(matchline)


For a sample input file

>>cat /tmp/1.txt
This is a sample code for grep
we do no have any example for egrep


We get the below output

pythongrepinfiles.pyegrep/tmp/1.txtwedonohaveanyexampleforegrep


Now, lets use this module as package in another module.

File: finderror.py


importsysfromgrepinfilesimportfindpatterntxtfl=sys.argv[1]forlineinfindpattern('ERROR',txtfl):print(line)

when you run this function, we get the below output.


>>pythonfinderror.py/tmp/1.txtTraceback(mostrecentcalllast):File"finderror.py",line2,in<module>fromgrepinfilesimportfindpatternFile"/home/user/workspace/blog_examples/python_name_gaurd/grepinfiles.py",line9,in<module>ptrn,txtfl=sys.argv[1],sys.argv[2]IndexError:listindexoutofrange

Why is this error???

Magic variable called "__name__"

Now, lets modify the code slightly and run the same command.

File: grepinfiles.py


importsysdeffindpattern(ptrn,txtfl):print("Inside the module",__name__)withopen(txtfl)asf:forlineinf:ifptrninline:yieldline.rstrip('\n')if__name__=="__main__":ptrn,txtfl=sys.argv[1],sys.argv[2]formatchlineinfindpattern(ptrn,txtfl):print(matchline)

and

File: finderror.py


importsysfromgrepinfilesimportfindpatternif__name__=="__main__":txtfl=sys.argv[1]forlineinfindpattern('ERROR',txtfl):print(line)


Now, check the output for the modified source code


>>pythongrepinfiles.pyegrep/tmp/1.txt('Insidethemodule','__main__')wedonohaveanyexampleforegrep>>pythonfinderror.py/tmp/1.txt('Insidethemodule','grepinfiles')

Explanation

The main package which is invoked by the python interpreter will have __name__ variable set to __main__
Any other module/package which is invoked by main package/module will have __name__ as the module name itself.

So, when finderror.py was invoked,
  • finderror.py module will have __name__ set to __main__
  • grepinfiles.py module will have __name__ set to 'grepinfiles'
However, when only grepinfiles.py was invoked,
  • grepinfiles.py module will have __name__ set to '__main__'

Conclusion

Name guard is a mechanism to customize your python module/package to run any specific code for the module when invoked independently. Also, it is a mechanism to safeguard the code base which are not to be executed when invoked from other up-stream modules/functions.



Viewing all articles
Browse latest Browse all 13

Trending Articles