<jupyter_start><jupyter_text>我们在编写程序的时候，经常引用其他模块，包括Python内置的模块和来自第三方的模块。使用模块还可以避免函数名和变量名冲突。相同名字的函数和变量完全可以分别存在不同的模块中，因此，我们自己在编写模块时，不必考虑名字会与其他模块冲突。但是也要注意，尽量不要与内置函数名字冲突。如果不同的人编写的模块名相同怎么办？为了避免模块名冲突，Python又引入了按目录来组织模块的方法，称为包（Package）。举个例子，一个abc.py的文件就是一个名字叫abc的模块，一个xyz.py的文件就是一个名字叫xyz的模块。现在，假设我们的abc和xyz这两个模块名字与其他模块冲突了，于是我们可以通过包来组织模块，避免冲突。方法是选择一个顶层包名，比如mycompany，按照如下目录存放：<jupyter_code>'''
mycompany
├─ __init__.py
├─ abc.py
└─ xyz.py
'''<jupyter_output><empty_output><jupyter_text>引入了包以后，只要顶层的包名不与别人冲突，那所有模块都不会与别人冲突。现在，abc.py模块的名字就变成了mycompany.abc，类似的，xyz.py的模块名变成了mycompany.xyz。每一个包目录下面都会有一个__init__.py的文件，这个文件是必须存在的，否则，Python就把这个目录当成普通目录，而不是一个包。__init__.py可以是空文件，也可以有Python代码，因为__init__.py本身就是一个模块，而它的模块名就是mycompany。类似的，可以有多级目录，组成多级层次的包结构。比如如下的目录结构：<jupyter_code>'''
mycompany
 ├─ web
 │  ├─ __init__.py
 │  ├─ utils.py
 │  └─ www.py
 ├─ __init__.py
 ├─ abc.py
 └─ xyz.py
'''<jupyter_output><empty_output><jupyter_text>文件 www.py 的模块名就是mycompany.web.www，两个文件utils.py的模块名分别是mycompany.utils和mycompany.web.utils。 自己创建模块时要注意命名，不能和Python自带的模块名称冲突。例如，系统自带了sys模块，自己的模块就不可命名为sys.py，否则将无法导入系统自带的sys模块。 总结模块是一组Python代码的集合，可以使用其他模块，也可以被其他模块使用。创建自己的模块时，要注意：模块名要遵循Python变量命名规范，不要使用中文、特殊字符；模块名不要和系统模块名冲突，最好先查看系统是否已存在该模块，检查方法是在Python交互环境执行import abc，若成功则说明系统存在此模块。  使用模块Python本身就内置了很多非常有用的模块，只要安装完毕，这些模块就可以立刻使用。我们以内建的sys模块为例，编写一个hello的模块：<jupyter_code>#！/user/bin/env python3
# -*- coding:utf-8 -*-
'a test moudle'

__author__='zengchao'
import sys
def test():
    args=sys.argv
    if len(args)==1:
        print('Hello,world!')
    elif len(args)==2:
        print('Hello,%s!'%args[1])
    else:
        print('Too many arguments!')
if __name__=="__main__":
    test()<jupyter_output>Too many arguments!<jupyter_text>第1行和第2行是标准注释，第1行注释可以让这个hello.py文件直接在Unix/Linux/Mac上运行，第2行注释表示.py文件本身使用标准UTF-8编码；第4行是一个字符串，表示模块的文档注释，任何模块代码的第一个字符串都被视为模块的文档注释；第6行使用__author__变量把作者写进去，这样当你公开源代码后别人就可以瞻仰你的大名； 导入sys模块后，我们就有了变量sys指向该模块，利用sys这个变量，就可以访问sys模块的所有功能。sys模块有一个argv变量，用list存储了命令行的所有参数。argv至少有一个元素，因为第一个参数永远是该.py文件的名称，例如：运行python3 hello.py获得的sys.argv就是 ['hello.py']；运行python3 hello.py Michael获得的sys.argv就是 ['hello.py', 'Michael]。<jupyter_code># 最后，注意到这两行代码：

if __name__=='__main__':
    test()<jupyter_output><empty_output><jupyter_text>当我们在命令行运行hello模块文件时，Python解释器把一个特殊变量__name__置为__main__.而如果在其他地方导入该hello模块时，if判断将失败，因此，这种if测试可以让一个模块通过命令行运行时执行一些额外的代码，最常见的就是运行测试。  作用域在一个模块中，我们可能会定义很多函数和变量，但有的函数和变量我们希望给别人使用，**有的函数和变量我们希望仅仅在模块内部使用**。在Python中，是通过‘_’前缀来实现的。正常的函数和变量名是公开的（public），可以被直接引用，比如：abc，x123，PI等；类似__xxx__这样的变量是特殊变量，可以被直接引用，但是有特殊用途，比如上面的__author__，__name__就是特殊变量，hello模块定义的文档注释也可以用特殊变量__doc__访问，我们自己的变量一般不要用这种变量名；类似_xxx和__xxx这样的函数或变量就是非公开的（private），不应该被直接引用，比如_abc，__abc等；之所以我们说，private函数和变量“不应该”被直接引用，而不是“不能”被直接引用，是因为Python并没有一种方法可以完全限制访问private函数或变量，但是，从编程习惯上不应该引用private函数或变量。private函数或变量不应该被别人引用，那它们有什么用呢？请看例子：<jupyter_code>def _private_1(name):
    return 'Hello, %s' % name

def _private_2(name):
    return 'Hi, %s' % name

def greeting(name):
    if len(name) > 3:
        return _private_1(name)
    else:
        return _private_2(name)<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.1204582651391162, 'fraction_numerical': 0.007201309328968904, 'mean_word_length': 11.576131687242798, 'pattern_counts': {'":': 1, '<': 20, '<?xml version=': 0, '>': 21, 'https://': 0, 'lorem ipsum': 0, 'www.': 3, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '5', 'dir': 'jupyter-structured-clean-dedup', 'id': '370931', 'license': 'MIT', 'n_tokens_mistral': 2070, 'n_tokens_neox': 2301, 'n_words': 93, 'path': 'module.ipynb', 'repo_name': 'Neekky/Study-Python', 'size': '3055'}