工欲善其事,必先利其器

# 环境:Python3.6 + win10
# 目录结构:
D:\test\ # 目录
├─ t1.py # 文件
└─ t2.py # 文件

让模块如脚本一样运行

在Python中,可以说,每一个py文件都可以说是一个模块,那么每一个模块不仅仅能被调用,也要负责本身的逻辑,如我们在模块t1中定义了一个登录函数并实现登录逻辑:

# t1.py
def login(user, pwd):
if user == '张开' and pwd == '':
return 'login successful'
return 'login error' user, pwd = input('user: ').strip(), input('pwd: ').strip()
print(login(user, pwd))

t1.py

那么,这个模块在自己使用的时候,肯定没有问题。但是有一天,这个牛逼的模块被别人使用了,在t2中调用了t1的注册功能:

# t1.py
def register():
user, pwd = input('user: ').strip(), input('pwd: ').strip()
if user == '张开' and pwd == '':
return 1
return 0 def login(user, pwd):
if user == '张开' and pwd == '':
return 'login successful'
return 'login error' user, pwd = input('user: ').strip(), input('pwd: ').strip()
print(login(user, pwd))

被t2.py 调用了的t1.py

# t2.py
import t1
def register():
if t1.register():
return 'register successful'
return 'register error'
print(register()) '''
user: a
pwd: a
login error
user: a
pwd: a
register error
'''

t2.py

那么,在t2模块内部要实现注册的时候,想到t1不是实现了一个注册的功能了吗?我们就要避免重复造轮子,就直接调过来用了,但是问题来了,当我们在调用一个模块的时候,该模块内的代码会先执行一遍,也就是t2模块示例代码最后展示的交互结果。当t2模块内的代码执行到import t1的时候,触发了原本t1模块的执行,t1模块内部代码从上往下执行,就执行到了登录逻辑。等登录逻辑执行完毕,程序回到t2模块继续往下执行。也就执行到了t2内部的注册函数的执行。而t2的注册函数此时又调用了t1模块的注册的函数的执行,等注册逻辑执行完毕,程序往下继续执行——没有代码,程序结束。

由上述示例可以见到,我们在t2模块调用t1模块的时候,只想调用注册函数,并不想触发t1登录逻辑的执行,那么,该怎么办呢?

if __name__ == "__main__":

我们首先看一下模块内自带都有哪些属性:

# t1.py
print(dir())
'''
['__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__']
'''

在上述的打印列表内,此时,__name__属性在这里对我们有帮助,那么我们来研究一个__name__属性是什么鬼?

我们先在各自模块内部打印一下__name__属性。

# t1.py
print('module t1.__name__:', __name__, type(__name__))
'''
module t1.__name__: __main__ <class 'str'>
'''
# t2.py
# import t1
print('module t2.__name__: ', __name__, type(__name__))
'''
module t2.__name__: __main__ <class 'str'>
'''

通过上例可以看到,各模块各自运行的结果一致,__name__属性都返回了一个str类型的__main__结果,你可能说,这没啥啊,扯半天淡就这看这个了?别急,我们放开t2模块的import t1注释再看:

# t1.py
print('module t1.__name__:', __name__, type(__name__))
'''
module t1.__name__: __main__ <class 'str'>
'''
# t2.py
import t1
print('module t2.__name__: ', __name__, type(__name__))
'''
module t1.__name__: t1 <class 'str'>
module t2.__name__: __main__ <class 'str'>
'''

通过执行t2模块,发现一个有趣的现象,在导入t1的时候,触发了t1模块的执行,但是,看看此时t1的打印是什么,没错,是t1的模块名!而单独运行t1的时候,结果仍不变,还是__main__。

那么,由此可以做些手脚了,我们通过__name__返回不同的字符串(自己调用返回__main__,被调用时返回自己的模块名),来解决上面那个登录逻辑被执行的问题。那么,我们就在t1中加上一句话:

# t1.py
def register():
user, pwd = input('user: ').strip(), input('pwd: ').strip()
if user == '张开' and pwd == '':
return 1
return 0 def login(user, pwd):
if user == '张开' and pwd == '':
return 'login successful'
return 'login error' if __name__ == '__main__':
user, pwd = input('user: ').strip(), input('pwd: ').strip()
print(login(user, pwd))

t1.py

# t2.py
import t1
def register():
if t1.register():
return 'register successful'
return 'register error'
print(register())
'''
user: 张开
pwd: 666
register successful
'''

t2.py

在t1模块中,当__name__属性返回是字符串__main__的时候,这说明是此次执行是t1模块自己被自己调用,那么我们就把想要实现的逻辑放到该if语句内,表明自己调用时执行。

而当别的模块如t2调用t1的时候,__name__属性返回了t1的模块名,那么t1不等于__main__,t1模块内部的if语句也就不会执行。这样就解决了上例中登录的问题。


that's all

if __name__ == "__main__":的更多相关文章

  1. python中if __name__ == "__main__":用法解析

    __name__: __name__作为模块的内置属性,简单点说呢,就是.py文件的调用方式. __main__: 如果__name__等于"__main__"就表示是直接执行. ...

  2. Python if __name__ == '__main__':

    python属于脚本语言,只能逐行运行, if __name__ == '__main__':这句相当于main(),即首先执行这条语句.

  3. 浅析 if __name__ == __main__ :

    有句话经典的概括了这段代码的意义: “Make a script both importable and executable” 意思就是说让你写的脚本模块既可以导入到别的模块中用,另外该模块自己也可 ...

  4. python中if __name__ == '__main__' :main(()

    例如: if __name__ == '__main__': main() 如果运行的是主函数的话,执行下一句main() 如果作为模块被其他文件导入使用的话,我们就不执行后面的main()什么的. ...

  5. Python中if __name__ == '__main__':的作用和原理

    if __name__ == '__main__':的作用 一个python文件通常有两种使用方法,第一是作为脚本直接执行,第二是 import 到其他的 python 脚本中被调用(模块重用)执行. ...

  6. 使用unittest,if __name__ == '__main__':里代码不执行的解决办法

    参考:https://www.cnblogs.com/hanmk/p/8656574.html

  7. if __name__ == "__main__": 怎么理解?

    参考:https://www.cnblogs.com/Neeo/p/9504779.html 总结: 1.防止模块间调用时,执行被调用模块实例化执行,换句话说,就是不要执行调用模块原来实例化的内容 2 ...

  8. Python3:if __name__ == '__main__' 详解

    一般在风格比较好的代码中会有一行if __name__ == '__main__' :代码,这里说明一下这句代码的用处,先上两个代码test1.py和test2.py: # test1.py prin ...

  9. 转载:Python中的if __name__ == '__main__'

    刚开始学习Python时,对于有些书出现的函数带有“if __name__ == '__main__'”总是迷惑不解,比如<dive into Python>中开头的哪个根据输入的数字计算 ...

随机推荐

  1. 新版的 Springsecurity request.getRequestDispatcher).forward(request, response); 404 问题,已解决

    旧版本的 可以直接 转发登陆 request.getRequestDispatcher).forward(request, response); 新版本的转发会404,原因 SpringSecurit ...

  2. J - Printer Queue 优先队列与队列

    来源poj3125 The only printer in the computer science students' union is experiencing an extremely heav ...

  3. metasploit 常用命令备忘

    metasploit 常用命令备忘    MSFconsole Commands-------------------------------------24show exploits 查看所有exp ...

  4. 浅谈SFTP和FTP的区别

    一.适用场景 我们平时习惯了使用ftp来上传下载文件,尤其是很多Linux环境下,我们一般都会通过第三方的SSH工具连接到Linux,但是当我们需要传输文件到Linux服务器当中,很多人习惯用ftp来 ...

  5. Codeforces 1090D - Similar Arrays - [思维题][构造题][2018-2019 Russia Open High School Programming Contest Problem D]

    题目链接:https://codeforces.com/contest/1090/problem/D Vasya had an array of n integers, each element of ...

  6. ssh无输入密码登录问题

    每天一个Linux命令:ps命令 ssh原理和运用(一):远程登录 http://www.ruanyifeng.com/blog/2011/12/ssh_remote_login.html SSH是每 ...

  7. mongo笔记2

    速度和持久性 用户可以选择写入语义,决定是否开启journaling日志记录,通过这种方式来控制速度和持久性的平衡,默认情况下写入都是fire-and-forget,写操作通过tcp套接字发送,不要求 ...

  8. [efficiency] emacs入门

    一. 没记错的话,这可能是第三次读emacs tutorial了.前两次读的非常慢,也不记得有没有读完了.总之最后都忘光了. 这次读的很顺畅,利用工作的空闲时间加上今天晚上(周日).总算是读完了. 没 ...

  9. 《nginx - 基本操作/配置》

    一:基本操作 - 开启 Nginx nginx -c nginx.conf -  Nginx 的平滑重启 kill -HUP nginx主进程号(平滑重启) -  停止 Nginx * Kill -Q ...

  10. 如何将本地大文件通过终端上传到linux服务器

    第一种方式:  SecureCRT下   上传文件只需在shell终端仿真器中输入命令“rz”,即可从弹出的对话框中选择本地磁盘上的文件,利用Zmodem上传到服务器当前路径下.   下载文件只需在s ...