工欲善其事,必先利其器

# 环境: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. C# 不安装Oracle客户端情况下,如何连接到Oracle数据库

    简介: 在我们开发应用场景经常碰到需要连接Oracle数据库,这也是相当常见的一种情况.一般.Net环境连接Oracle数据库,可以通过TNS/SQL.NET 配置文件,而 TNS 必须要 Oracl ...

  2. lucene学习教程

    1Lucene的介绍 ①Lucene是什么: 是一个开放源代码的全文检索引擎工具包,但它不是一个完整的全文检索引擎,而是一个全文检索引擎的架构,提供了完整的查询引擎和索引引擎,部分文本分析引擎 ②Lu ...

  3. springboot+mybatis+druid数据库连接池

    参考博客https://blog.csdn.net/liuxiao723846/article/details/80456025 1.先在pom.xml中引入druid依赖包 <!-- 连接池 ...

  4. 01day

    01 cpu 内存 硬盘 操作系统  CPU:中央处理器,相当于人大脑.   (运行速度飞机)   内存:临时存储数据. 8g,16g,          (高铁)   1,成本高.   2,断电即消 ...

  5. 程序员调 Bug 的样子,非常真实

    程序员调 Bug 的样子,非常真实

  6. sqlserver为不同数据库建立不同访问权限的帐号

    正式服务器中,为了安全.互不干扰,会给个DB库分配不同的账号,A库有ARead\AReadWrite\AOwn账号,B库有BRead\BReadWrite\BOwn账号.需要配置出来,甚至还能限制AR ...

  7. Xcode工程编译错误之iOS开发之Xcode9报错 Compiling IB documents for earlier than iOS7 is no longer supported.

    概要: 在我们升级到Xcode9时,最低的编译版本为iOS8,但是在使用一些SDK的时候就会报出Compiling IB documents for earlier than iOS7 is no l ...

  8. [qemu] qemu从源码编译安装

    环境:CentOS7-1804 下载最新的源码: ┬─[tong@T7:~/Src/thirdparty/PACKAGES]─[:: AM] ╰─>$ axel https://download ...

  9. npm更新指定的组件

    1.例如:react-router已经更新到4.x版本,想要下载2.x版本,可以通过下面命令 npm install --save-dev react-router@2.8.1 或 npm insta ...

  10. Mac破解免费office软件

    一.下载安装包及破解工具 地址: https://pan.baidu.com/s/1hugtoLQ 密码: s5in 附官网地址 文件夹中包含三个文件: Office16安装文件 Microsoft_ ...