# 今日主要内容:
# 1. 认识模块
# 模块可以认为是一个py文件. 模块实际上是我们的py文件运行后的名称空间
# 导入模块:
# 1. 判断sys.modules中是否已经导入过该模块
# 2. 开辟一个内存
# 3. 在这个内存中执行该py文件
# 4. 给这个内存起个名字, 一般用的是py文件的名字。返回给导入方
# 如果你的py文件是启动文件, 名字是__main__
#
# 程序的入口一般是:
# if __name__ == "__main__":
# pass
# 2. import
# import 模块名
# 模块名.属性/方法/类
#
# 每个模块都有自己的独立的名称空间,每个都有一个global, 互相并不影响
# 模块.属性 = 值. # 不要这么干
#
# 3. from xxx import xxx
# from 模块 import 函数/变量
# 当作自己的变量或者函数来使用
#
# from xxx import * 导入所有
# 导入的内容都可以起别名 as
# 一、模块
# ⾸先,我们先看⼀个老⽣常谈的问题. 什么是模块. 模块就是⼀个包含了python定义和声
# 明的⽂件, ⽂件名就是模块的名字加上.py后缀. 欢聚话说我们⽬前写的所有的py⽂件都可以
# 看成是⼀个模块但是我们import加载的模块⼀共分成四个通⽤类别:
#
# 1. 使⽤pyhton编写的py⽂件
# 2. 已被变异为共享库或者DLL或C或者C++的扩展
# 3. 包好⼀组模块的包.
# 4. 使⽤c编写并连接到python解释器的内置模块
# 为什么要使⽤模块? 为了我们写的代码可以重⽤. 不⾄于把所有的代码都写在⼀个⽂件
# 内. 当项⽬规模比较⼩的时候. 完全可以使⽤⼀个py搞定整个项⽬的开发. 但是如果是⼀个⾮
# 常庞⼤的项⽬. 此时就必须要把相关的功能进⾏分离. ⽅便我们的⽇常维护. 以及新项⽬的开
# 发.
# 导入模块的两种方式:
# 1.import 模块
# 2、from xxx import xxxx
# ⼆. import
# 在Python中模块是不能够重复导入的. 当重复导入模块时. 系统会根据sys.modules来判
# 断该模块是否已经导入了. 如果已经导入. 则不会重复导入
# import sys
# # import re
# print(sys.modules.keys())
# 导入模块的时候都做了些什么? ⾸先. 在导入模块的⼀瞬间. python解释器会先通过
# sys.modules来判断该模块是否已经导入了该模块. 如果已经导入了则不再导入. 如果该模块
# 还未导入过. 则系统会做三件事.
# 1. 为导入的模块创⽴新的名称空间
# 2. 在新创建的名称空间中运⾏该模块中的代码
# 3. 创建模块的名字. 并使⽤该名称作为该模块在当前模块中引⽤的名字.
# 注意. 由于模块在导入的时候会创建其⾃⼰的名称空间. 所以. 我们在使⽤模块中的变量
# 的时候⼀般是不会产⽣冲突的
# import yitian(其他自建模块)
# main_person_man = "胡⼀菲"
# def fight_in_shaolin():
# print(main_person_man, "⼤战曾⼩贤")
# print(yitian.main_person_man) # 张⽆忌 (原来模块的变量没右边)
# print(main_person_man) # 胡⼀菲(当前模块变量)
# yitian.fight_in_shaolin() # 倚天屠⻰记中的
# fight_in_shaolin() # ⾃⼰的
# 特别特别要注意. 如果我们在不同的模块中引入了同⼀个模块. 并且在某⼀个模块中改
# 变了被引入模块中的全局变量. 则其他模块看到的值也跟着边. 原因是python的模块只会引入
# ⼀次. ⼤家共享同⼀个名称空间
# 上述问题出现的原因:
# 1. ⼤家共享同⼀个模块的名称空间.
# 2. 在⾦庸⾥改变了主⻆的名字
# 如何解决呢?
# ⾸先. 我们不能去改python. 因为python的规则不是我们定的. 只能想办法不要改变主
# ⻆的名字. 但是. 在⾦庸⾥我就有这样的需求. 那此时就出现了. 在⾦庸被执⾏的时候要执⾏
# 的代码. 在⾦庸被别⼈导入的时候我们不想执⾏这些代码. 此时, 我们就要利⽤⼀下__name__
# 这个内置变量了. 在Python中. 每个模块都有⾃⼰的__name__ 但是这个__name__的值是不
# 定的. 当我们把⼀个模块作为程序运⾏的入⼝时. 此时该模块的__name__是"__main__" , ⽽
# 如果我们把模块导入时. 此时模块内部的__name__就是该模块⾃⾝的名字
# 我们可以利⽤这个特性来控制模块内哪些代码是在被加载的时候就运⾏的. 哪些是在模
# 块被别⼈导入的时候就要执⾏的. 也可以屏蔽掉⼀些不希望别⼈导入就运⾏的代码. 尤其是测
# 试代码.
# ⼀次可以引入多个模块
# import time, random, json, yitian
# 正确的导入模块的顺序:
# 1. 所有的模块导入都要写在最上⾯. 这是最基本的
# 2. 先引入内置模块
# 3. 再引入扩展模块
# 4. 最后引入你⾃⼰定义的模块
# 三. from xxx import xxx
# 第⼀⼤块关于import就说这么多. 接下来. 我们来看from xxx import xxx这种导入模块的
# 效果. 在使⽤from的时候, python也会给我们的模块创建名称空间. 这⼀点和import是⼀样
# 的. 但是from xxx import xxx的时候. 我们是把这个空间中的⼀些变量引入过来了. 说⽩了. 就
# 是部分导入. 当⼀个模块中的内容过多的时候. 我们可以选择性的导入要使⽤的内容.
# 最后. 看⼀下from的坑. 当我们从⼀个模块中引入⼀个变量的时候. 如果当前⽂件中出现
# 了重名的变量时. 会覆盖掉模块引入的那个变量(原来那个没变只是在新的全局空间新的变量将其覆盖了).
from yitian import main_person_man
# import yitian
# main_person_man = "超级⼤灭绝"
# print(main_person_man) # 超级⼤灭绝
# print(yitian.main_person_man) # 张无忌