zoukankan      html  css  js  c++  java
  • Python if __name__ == "__main__":

    before

    Python3.6.8 + win10

    刚学Python时,你可能会经常遇到这样一行代码:

    if __name__ == "__main__":
    

    然后你可能对这行代码有点不太理解。
    本篇就为你讲解这行代码的意思,为什么要写用这行代码。
    我们提前准备这样一个目录结构:

    D:\test\        # 目录
        ├─ t1.py    # 文件
        └─ t2.py    # 文件
    

    让模块如脚本一样运行

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

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

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

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

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

    if name == "main":

    我们首先看一下模块内自带都有哪些属性,这里以t1为例:

    # 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中代码不变,运行t2.py

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

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

    • 当一个模块单独执行的时候,这个模块的__name__属性返回的是字符串类型的__main__
    • 当一个模块被别人导入触发执行的时候,这个模块的__name__属性返回的是该模块的模块名。

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

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

    在t1模块中,当__name__属性返回是字符串__main__的时候,这说明是此次执行是t1模块单独执行,那么我们就把想要实现的逻辑放到该if语句内,表明自己调用时执行。
    而当别的模块如t2调用t1的时候,t1__name__属性返回了t1的模块名,而不是__main__,所以t1模块内部的if语句也就不会执行,这样就解决了之前的登录问题。
    此时再运行t2.py,你会发现一切都正常了:

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

    现在,你知道if __name__ == '__main__':是干什么的了么?


    that's all
  • 相关阅读:
    APP开发收藏的几个网址,APP性能监测
    MAC 安装STF
    更新react 之后 出现 can not find ‘@babel/runtime/helpers/esm/createSuper’ 提示
    react 相关笔记
    jenkins 配置子节点 关键在端口号和下方代理配置
    移动APP测试8点注意事项
    自动部署java项目,热部署方式
    ubuntu搭建elk服务器
    数据库常用操作,sql server; mysql
    windows 关闭端口占用及其他常见操作
  • 原文地址:https://www.cnblogs.com/Neeo/p/9504779.html
Copyright © 2011-2022 走看看