If __name__ == Raise your hand, if you write the code under'__main__'

happy New Year. It's early in the new year, but I have something to say to you, teachers.

In python code, raise your hand if you write the code under if \ _ \ _ name \ _ \ _ =='\ _ \ _ main \ _ \ _'.

Someone who writes code under if \ _ \ _ name \ _ \ _ =='\ _ \ _ main \ _ \ _', like this.

#! usr/bin/python
# -*- coding: utf-8 -*-
from __future__ import unicode_literals, print_function, absolute_import
import sys


def say_args(kind, data_list):
    print("kind:", kind, " data:", data_list)


if __name__ == '__main__':
    args = sys.argv[1:]
    assert args

    kind = args[0].lower()
    data_list = [x.lower() for x in args[1:]]

    say_args(kind, data_list)

People who write such code, teachers, don't get angry, so raise your hand.

Did you notice that such code ** pollutes the global scope namespace **? If you are aware of it and understand it before writing, you can drop your hand.

if \ _ \ _ name \ _ \ _ =='\ _ \ _ main \ _ \ _'Below is the global scope

Yes, if \ _ \ _ name \ _ \ _ =='\ _ \ _ main \ _ \ _'Below is the global scope. The variables defined there are ** all global variables **.

In the above code, args, `kind```, `` data_list```, which are supposed to be local variables, become global variables. Therefore, writing the following code will not cause an error.

def say_args(kind, data_list):
    print("kind:", kind, " data:", data_list)
    #The global variable args is referenced, which does not result in an error when referring to undefined args
    print("args: ", args)

This is a source of annoying bugs, not an error when executed directly, but a Name Error when called as a module.

** So don't dissipate the python teacher's language specs. ** **

Dr. PyCharm is also angry about this matter, saying "Shadows name'kind' form outer scope".

2017-01-01_11h04_25.png

Solution

If you want to write code under if \ _ \ _ name \ _ \ _ =='\ _ \ _ main \ _ \ _', wrap it in a function.

#! usr/bin/python
# -*- coding: utf-8 -*-
from __future__ import unicode_literals, print_function, absolute_import
import sys


def main(args):
    assert args

    kind = args[0].lower()
    data_list = [x.lower() for x in args[1:]]

    say_args(kind, data_list)


def say_args(kind, data_list):
    print("kind:", kind, " data:", data_list)


if __name__ == '__main__':
    main(sys.argv[1:])

The global scope namespace is not polluted by wrapping it in the main function. Also, by wrapping it in the main function, you can write the main process at the beginning, which improves the visibility of the code.

If you are new to python, it is safe to wrap it in a function.

If you are worried about other things, please use PyCharm teacher, it's like a small mother-in-law, but it will point out the bad points of the take-home code. ~~ pyflask Sensei ~~ pyflakes Sensei and pylint Sensei are fine, but pylint Sensei is stricter. (1/1 correction: There is no pyflask teacher, it was a mistake of pyflakes teacher)

That's all the teacher wanted to say.

Then, if you say, "If you wrap it in the main function, you can create a useless main function when you want to use it as a module," let's discuss it individually with the teacher later in the staff room.

I wrote a make-up class

[[Supplementary course] If \ _ \ _ name \ _ \ _ =='\ _ \ _ main \ _ \ _', please raise your hand](http://qiita.com/pashango2/ items / 3834221353e4d25e0d69)

2017-01-02 Corrected about variable "x"

We will correct it in response to Mr. knoguchi's comment. If you make corrections in the article, it will be difficult to read the article, so it has been moved to the end of the sentence.

** [Sentence before correction] ** In the above code, args, `kind```, data_list```, which is intended as a local variable, ~~ even the temporary variable `x``` ~~ global It becomes a variable.

def say_args(kind, data_list):
    print("kind:", kind, " data:", data_list)
    #A global variable x is referenced that does not result in an error when referencing undefined x
    print("x: ", x)

`` `x``` used in the comprehension will not be a global variable, it will be an error.

However, it doesn't seem to cause an error when running PyCharm, because PyCharm reuses global frames for speed. It's a lesson that you can't just check the result on PyCharm.

I would like to thank Mr. knoguchi again. "Variable leak of list comprehension is a problem of rebinding" in the comment is one of the addictive points in the inclusion notation, so please also see the comment.

Recommended Posts

If __name__ == Raise your hand, if you write the code under'__main__'
[Supplementary course] If __name__ == If you write the code under'__main__', raise your hand.
[Python beginner] If __name__ == Move your hand to understand'__main__'.
If you want your colleagues to use the same language
If you ride the Titanic ... die.
If you are told cannot by Python import, review the file name
If you think the PyCharm environment is broken, it's because of the file name
If you write the View decorator in urls.py in Django, the list will be higher.
If you know this much, you can write Python test code! ~ Super introductory edition ~