欢迎各位兄弟 发布技术文章

这里的技术是共享的

You are here

python中main.py是什么意思_关于python:什么是__main__.py? 有大用

目录

__init__.py

 Package 中 init 的作用

区分模块

绑定到当前的命名空间


__main__.py文件

if __name__ == '__main__':的作用




  1. ├──pkg
  2. │   ├── __init__.py
  3. │   ├── __main__.py
  1. 如果你希望 python 将一个文件夹作为 Package 对待,那么这个文件夹中必须包含一个名为 __init__.py 的文件,即使它是空的。

  2. 如果你需要 python 将一个文件夹作为 Package 执行,那么这个文件夹中必须包含一个名为 __main__.py 的文件。

在实际中,可以将pkg作为一个文件夹执行:python pkg
也可以将pkg作为一个Package执行:python -m pkg


__init__.py

  • __init__.py是编辑器用来标识package包的

如果你仅仅只是编写一个python程序,那么这个__init__.py可有可无,但是你要是想写一个包想写一个模块,想让这个包在别的程序中可以调用,那么这个文件一定要有,里面可以空着什么都不写,但是一定要有。

例子:

1. 现在package文件TestPy下有三个python文件,分别为Test.py、Test2.py、__init__.py

在这里插入图片描述

 Test.py

  1. def A():
  2. print("A()")
  3. def B():
  4. print("B()")

Test2.py

  1. from TestPy import *
  2. A()
  3. B()

__init__.py

  1. from TestPy.Test import *
  2. __all__ = ['A']

2. 使用一个包或者模块,有两种操作,精准导入和模糊导入

2.1. 精准导入
示例如下:

from  TestPy.Test import A

这样只能使用Test.A(),用什么就调用什么,大大增加了速度。
思考问题:
那么我们需要导入大量的方法,怎么办?一个一个导?

2.2. 模糊导入
示例如下:

from  TestPy.Test import *

使用 from package import * 的时候就把这个列表中的所有名字作为包内容导入。

作为包的作者,可别忘了在更新包之后保证 __all__ 也更新了啊。

以下实例在 file:sounds/effects/__init__.py 中包含如下代码:

__all__ = ["echo", "surround", "reverse"]

这表示当你使用from sound.effects import *这种用法时,你只会导入包里面这三个子模块。

如果 __all__ 真的没有定义,那么使用from sound.effects import *这种语法的时候,就不会导入包 sound.effects 里的任何子模块。他只是把包sound.effects和它里面定义的所有内容导入进来(可能运行__init__.py里定义的初始化代码)。

通常我们并不主张使用 * 这种方法来导入模块,因为这种方法经常会导致代码的可读性降低。不过这样倒的确是可以省去不少敲键的功夫,而且一些模块都设计成了只能通过特定的方法导入。

记住,使用 from Package import specific_submodule 这种方法永远不会有错。事实上,这也是推荐的方法。除非是你要导入的子模块有可能和其他包的子模块重名。


3. __init__.py里的 __all__

在 __all__中可以声明定义允许用户可以调用的方法,以在 __all__ 中限定用户调用的范围

入示例代码所示,只允许调用Test的A()方法

  1. from TestPy.Test import *
  2. __all__ = ['A']


如果强行调用Test的B()方法会报错,如截图所示

在这里插入图片描述


 Package 中 init 的作用

区分模块

在Python 中,一个 py文件,对应的就是一个模块。

在 my_package包 中创建三个子包 package_one、package_two、package_three

在这里插入图片描述


在编写的python程序中,不能同时导入两个同名的模块,而我们的程序又要用到这两个 py文件 里的内容,那么可以采用将这两个 py文件 放入两个不同的包下,通过导入不同包的方式进行区分,导入这两个不同的模块。

在 package_one 的 my_moudel 文件中定义类test1

  1. class test1():
  2. print('*' * 10)
  3. if __name__ == '__main__':
  4. pass

在 package_two 的 my_moudel 文件中定义类test2

  1. class test2():
  2. print('*' * 20)
  3. if __name__ == '__main__':
  4. pass

在 package_three 的 my_moudel 文件中定义类test3

  1. class test3():
  2. print('*' * 30)
  3. if __name__ == '__main__':
  4. pass

新建一个 my_print.py 文件,导入3个 my_moudel 模块

  1. import my_package.package_one.my_moudel
  2. import my_package.package_two.my_moudel
  3. import my_package.package_three.my_moudel
  4. f1 = my_package.package_one.my_moudel.test1
  5. f2 = my_package.package_two.my_moudel.test2
  6. f3 = my_package.package_three.my_moudel.test3
  7. # 运行 my_print.py文件,结果为:
  8. **********
  9. ********************
  10. ******************************

绑定到当前的命名空间

分别在子包的 init 文件中写入以下内容:

package_one

print('这是子包 one 的 init')

package_two

print('这是子包 two 的 init')

在父亲包 my_package 中写入以下内容:

print('这是父亲包 的 init')


新建一个 test.py 文件(可建在my_package 包外面),进行导包操作

只导入父模块 my_package

  1. import my_package
  2. # 运行test.py文件,结果为:
  3. # 这是父亲包 的 init

总结:只导入父模块的时候只会执行父模块中的 init

单独导入子模块 package_one

  1. import my_package.package_one
  2. #  运行test.py文件,结果为:
  3. # 这是父亲包 的 init
  4. # 这是子包 three 的 init

单独导入package_two

  1. import my_package.package_two
  2. #  运行test.py文件,结果为:
  3. # 这是父亲包 的 init
  4. # 这是子包 two 的 init

单独导入package_three

  1. import my_package.package_three
  2. #  运行test.py文件,结果为:
  3. # 这是父亲包 的 init
  4. # 这是子包 three 的 init

三个包均导入

  1. import my_package.package_one
  2. import my_package.package_two
  3. import my_package.package_three
  4. #  运行test.py文件,结果为:
  5. # 这是父亲包 的 init
  6. # 这是子包 one 的 init
  7. # 这是子包 two 的 init
  8. # 这是子包 three 的 init

总结:导入父模块中的子模块的时候,优先执行父模块中的 init ,再执行指定模块中的 init

也就是说,当我们去 import 一个 Package 的时候,它会隐性的去执行 __init__.py , 
而在 __init__.py 中定义的对象,会被绑定到当前的命名空间里面来。

有时候我们会这样去导入一个包下的所有模块:

  1. from my_package import *
  2. # 运行test.py文件,结果为:
  3. # 这是父亲包 的 init

但这个时候却并没有将相关的子模块导入进来,如果想采用这种导包的方式,也将子模块导入进来,或者导入某些特定的子模块进来,可采用对 父亲包的 init 文件进行编辑:

  1. print('这是父亲包 的 init')
  2. __all__ = ['package_one','package_three']
  3. # 这里的 __all__ 相当于导入 [] 里面定义的模块

此时再运行 test.py 文件

  1. from my_package import *
  2. #  运行test.py文件,结果为:
  3. # 这是父亲包 的 init
  4. # 这是子包 one 的 init
  5. # 这是子包 three 的 init

__main__.py文件


当我们创建一个Python包时,需有一个__init__.py文件,它是用来标识Python包的,用来与普通文件夹做区分;
我们同样可以在一个Python包中创建一个__main__.py文件,类似于if __name__ == "__main__",模块的__name__.py文件在通过命令行输入的时候作用等同于if __name__ == "__main__";

在命令行直接输入python -m package_name 就可以执行__main__.py文件
 

if __name__ == '__main__':的作用

一个python文件通常有两种使用方法,第一是作为脚本直接执行,第二是 import 到其他的 python 脚本中被调用(模块重用)执行。因此 if __name__ == 'main': 的作用就是控制这两种情况执行代码的过程,在 if __name__ == 'main': 下的代码只有在第一种情况下(即文件作为脚本直接执行)才会被执行,而 import 到其他脚本中是不会被执行的。

文章知识点与官方知识档案匹配,可进一步学习相关知识
普通分类: