(以下基本摘自《王纯业的python学习笔记》,所有命令均测试通过)
模块(module)是Python中非常重要的一个概念,模块其实就一些函数和类的集合文件,它能实现一些相应的功能,当我们需要使用这些功能的时候,直接把相应的模块导入到我们的程序中,我们就可以使用了。这类似于C语言中的include头文件,Python中我们用import导入我们需要的模块。
类似于头文件,模块也是需要系统的搜索路径的,下面的命令即是系统默认的搜索路径,当你导入一个模块时,系统就会在下面的路径列表中搜索相应的文件。
>>> sys.path
['C:/Python26/code', 'C:\\Python26\\Lib\\idlelib', 'C:\\WINDOWS\\system32\\python26.zip', 'C:\\Python26\\DLLs', 'C:\\Python26\\lib', 'C:\\Python26\\lib\\plat-win', 'C:\\Python26\\lib\\lib-tk', 'C:\\Python26', 'C:\\Python26\\lib\\site-packages', 'C:\\Python26\\lib\\site-packages\\win32', 'C:\\Python26\\lib\\site-packages\\win32\\lib', 'C:\\Python26\\lib\\site-packages\\Pythonwin', 'C:\\Python26\\lib\\site-packages\\wx-2.8-msw-unicode']
假如没有搜到相应内容就会报错。
>>> import xxx
Traceback (most recent call last):
File "", line 1, in
import xxx
ImportError: No module named xxx
当然我们也可以添加我们的搜索路径。调用列表的append方法即可。
sys.path.append(‘相对路径或者绝对路径’)
然后我们就可以加载我们自己的模块了。那么如何创建我们自己的模块呢,简单看一下。首先我们在当前目录创建一个名为testmodule.py的文件,内容如下:
"""
this only is a very simple test module
"""
age=0 # a simple attribute
def sayHello(): # a simple function in a module
print 'Hello'
if __name__=="__main__":
sayHello()
然后我们导入这个模块就可以使用它的变量和函数了。
>>> import test_module
>>> test_module.age
0
>>> test_module.sayHello()
Hello
>>>
当然我们也可以这样:
>>> from test_module import age,sayHello
>>> age
0
>>> sayHello
>>> sayHello()
Hello
>>> test_module
Traceback (most recent call last):
File "", line 1, in
test_module
NameError: name 'test_module' is not defined
>>>
注意两种方法的不同。 From 并没有把test_module 引进来,所以当前namespace没有test_module这个name。所以报错。
命名空间(name space)是从名称(name)到对象(object)的映射(map)。当一个name映射到一个object上时,这个name和这个object就绑定(bind)了。
Python中一切都是对象(object),包括function,module,class,package本身。这些对象都在内存中真正的存在,就 像活在世上的每一个人。但是我们怎么找到这些object呢?用name给每个object起名。每个名字只对应一个对象,一个对象可以由多个名字。但是 name不是object本身。
Python中有很多name space,常用的有:build—in name space(内建命名空间)global name space(全局命名空间),local name space(局部命名空间)。在不同的name space中的name是没有关系的。
每个object都有自己的name space,可以通过object.name的方式访问object的name space中的name,每个object的name都是独立。即使在别的name space中有与之相同的name,它们也是没有任何关联的。
每一个object,都有自己的name space,name space都是动态创建的,每一个name space的生存时间也不一样。
一个模块的name space是这个module被import的时候创建的。每个module都有一个_name_的attribute,用来表示当前module的名字。所以每个module都有这样的代码:
If _name_= = “_main_”:
sayHello() #测试代码
下面是测试代码
>>> import sys
>>> sys.path.append('C:\Python26\code')
>>> sys.path
['C:\\Python26\\Lib\\idlelib', 'C:\\WINDOWS\\system32\\python26.zip', 'C:\\Python26\\DLLs', 'C:\\Python26\\lib', 'C:\\Python26\\lib\\plat-win', 'C:\\Python26\\lib\\lib-tk', 'C:\\Python26', 'C:\\Python26\\lib\\site-packages', 'C:\\Python26\\lib\\site-packages\\win32', 'C:\\Python26\\lib\\site-packages\\win32\\lib', 'C:\\Python26\\lib\\site-packages\\Pythonwin', 'C:\\Python26\\lib\\site-packages\\wx-2.8-msw-unicode', 'C:\\Python26\\code']
>>> import test_module
>>> dir(test_module)
['__builtins__', '__doc__', '__file__', '__name__', '__package__', 'age', 'sayHello']
>>> test_module.__name__
'test_module'
>>>
我们看到这个module有一个__name__属性。因为这个module在被import的时候,它的name space中创建了一个内置的name ,__name__,用来表示module的文件名称。所以import的时候,测试代码sayHello()并没有运行,因为if条件不满足。但是如果我们直接运行该模块的话,那么module的name space就是global name space,这时Python自动把global name space中的__name__ 设为__main__,测试代码就会运行,打印出Hello。
当调用一个function的时候,function的local name space被创建了,当function返回的时候或者异常中断的时候,local name space被删除了。
作用域(scope),是python中的代码从字面意义上可以直接访问的name集合。
LGB的规则用scope的概念来解释就是:和任何代码执行的时候,都至少有三个scope:local name space,global name space ,buildin name space (LGB)。看下面的例子:
>>> def sayHello():
print 'Hello'
>>> saidHello=sayHello
>>> saidHello
>>> sayHello
>>> sayHello()
Hello
>>> saidHello()
Hello
>>>
可以看到sayHello和saidHello不过是两个名字,他们都是指的同样的object,就像一个人有两个名字一样。
用del可以从一个name space删除一个name,如:
>>> a=1
>>> b=a
>>> a
1
>>> b
1
>>> id(a)
11364056
>>> id(b)
11364056
>>> del a
>>> a
Traceback (most recent call last):
File "", line 1, in
a
NameError: name 'a' is not defined
>>> b
1
可以看到a和b指向同一个object,然后我们del a,只是从name space清除了一个name和object的绑定关系,如果没有其他name和这个对象bind,那么才是真正的清除object。实际上python中使用了智能指针技术,每个name都和指向object的指针相关联,每一个object都有一个reference counter记住有多少个name和这个object相关联。每次bind,reference counter都加1,每次删除bind,都减1,只有当reference counter为0时,object才真正被删除。