模块间相互独立相互引用是任何一种编程语言的基础能力。对于“模块”这个词在各种编程语言中或许是不同的,但我们可以简单认为一个程序文件是一个模块,文件里包含了类或者方法的定义。
对于编译型的语言,比如C#中的一个.cs文件,Java中的一个.java或者编译后的.class文件可以认为是一个模块(但常常不表述为模块);
对于解释型的语言会更加直观些,比如PHP的.php文件,在Python中就是.py文件可以认为是一个模块。在“模块”之上有“包”,主要是为了方便组织和管理模块。比如C#中编译后的.dll文件(但常常不表述为包Package,而是库Library),Java将.class打包后的.jar文件,PHP的.phar文件(模仿Java包),在Python中一个特殊定义的文件夹是一个包,可以打包为egg文件。
但对于解释型语言“包”并没有编译成低级语言而后打包的意思,只是更加方便模块化和管理模块间的依赖。每种编程语言对于模块和包管理都有一定的约定,不了解这些约定,那会给学习这种语言的带来障碍。下面我想来梳理一下Python的这些约定。
animal 包:_init_.py文件代码是在包或者包内模块被引用时执行的,因而可以在其中做一些初始化的工作。修改animal文件夹中__init__.py文件如下
animal/__init__.py:
print "__init__"
from pet import name as pet_name, run as pet_run
#from animal.pet import name as pet_name, run as pet_run
#from .pet import name as pet_name, run as pet_run
animal/pet.py
# -*- coding: utf-8 -*-
# 如果想在被引用的时候使用 * 通配符,又不想引用模块中的所有变量,
# 可以在模块中用变量__all__进行限制,如修改本文件 pet.py,限制只引用ID和run两个变量名。
__all__ = ['ID','run']
ID = 2
name = "This pet"
print name
def run(somewhere):
print name,'runs', somewhere
person.py:
# -*- coding: utf-8 -*-
ID = 1
name = "This person"
print name
def say(something):
print name,'says', something
import animal
def have():
print name,'has', pet_name
The output is like:
>>>
>>> import person
This person
__init__
This pet
>>>
>>> import person # 第二次执行 import person 居然没有输出了,是因为 person 模块已经加载到内存里了,
>>> 所以第二次 import 的时候,就直接从 sys.modules 返回了,就不再根据 sys.path 去实际搜索模块了
>>>
>>> dir(person)
['ID', '__builtins__', '__doc__', '__file__', '__name__', '__package__', 'have',
'name', 'pet', 'pet_name', 'pet_run', 'say']
>>>
>>> print person.pet_name
This pet
>>>
>>> person.pet_run("nowhere")
This pet runs nowhere
>>>
在Python环境中引用person模块, person引用animal,并自动执行 _init_ 的代码加载相关变量,通过dir方法可以查看模块中的变量,其中两个下划线开始的变量每个模块都有,这些变量具有特殊的作用,是Python预定义的。
扩展: https://www.cnblogs.com/Zzbj/p/9607462.html
1. 在from import的过程中发生了哪些事情
from My_module import name
from My_module import read
1,要找到My_module
2,开空间,执行my_module
3,所有的My_module中的名字都存储在My_module所属的空间中
4,本文件空间中建立对应的变量名(name,read),分别取引用My_module空间中对应的名字
from My_module import name
from My_module import read
print(name) # 帅锅
read() # in read 帅锅
2. 引用模块的变量后,进行修改(看图)
from My_module import name
from My_module import read
print(name) # 帅锅
name = 'aaa'
read() # in read 帅锅
print(name) # aaa