我们在前面已经写好了一些方法和类, 希望能给在项目中的其它地方, 或者是别的项目中调用. 就可以把它放在一个模块里面.

最简单的封装模块的方法,就是, 什么都不用做. 刚刚写的python脚本已经是一个模块了.

一个最简单的模块

目录结构:

   |-- main.py
   |-- personmain.py

person.py:

#!/usr/bin/env python
# -*- coding: utf-8 -*-

class Person(object):
    def __init__(self, name, age, gender):
        self.name = name
        self.age = age
        self.gender = gender

    def introduce(self):
        print 'my name is %s, %s, %d years old' % (self.name, self.gender, self.age)

personmain.py

#!/usr/bin/env python
# -*- coding: utf-8 -*-

from person import Person  # 从同目录的person文件中引用了Person变量

p = Person("liujia", 28, u"男")
p.introduce()

组织在文件夹中

代码太多, 各种类和方法, 不想放同一个文件中. 希望能组织在一个文件夹中, 里面有多个文件, 把类分别存放.

   |-- shape
   |   |-- __init__.py
   |   |-- rectangle.py
   |   |-- square.py
   |-- shapemain.py

shape/square.py

#!/usr/bin/env python
# -*- coding: utf-8 -*-

class Square(object):
    def __init__(self, edge):
        super(Square, self).__init__()
        self.edge = edge

shapemain.py

#!/usr/bin/env python
# -*- coding: utf-8 -*-

from shape.square import Square

s = Square(10)
print s

要点就是, 在文件中放__init__.py, python就会这个文件夹做为了一个模块处理了!

python到哪里寻找模块?

我们刚刚引用的模块都是放在当前目录下.
但之前引用的time random等模块是放在哪里呢?
进而, 当import XXX的时候, python去哪里找这个XXX呢?

来看一段代码:

% python -c "import sys;print '\n'.join(sys.path)"

/Users/liujia/Applications/anaconda/lib/python2.7/site-packages/MySQL_python-1.2.4-py2.7-macosx-10.5-x86_64.egg
/Users/liujia/Applications/anaconda/lib/python2.7/site-packages/pip-1.5-py2.7.egg
/Users/liujia/Applications/anaconda/lib/python27.zip
/Users/liujia/Applications/anaconda/lib/python2.7
/Users/liujia/Applications/anaconda/lib/python2.7/plat-darwin
/Users/liujia/Applications/anaconda/lib/python2.7/plat-mac
/Users/liujia/Applications/anaconda/lib/python2.7/plat-mac/lib-scriptpackages
/Users/liujia/Applications/anaconda/lib/python2.7/lib-tk
/Users/liujia/Applications/anaconda/lib/python2.7/lib-old
/Users/liujia/Applications/anaconda/lib/python2.7/lib-dynload
/Users/liujia/Applications/anaconda/lib/python2.7/site-packages
/Users/liujia/Applications/anaconda/lib/python2.7/site-packages/PIL
/Users/liujia/Applications/anaconda/lib/python2.7/site-packages/setuptools-0.6c11-py2.7.egg-info

输出的第一行是空行, 其实是个空格…, 代表了当前目录.

sys.path是个列表, 里面存储着几个路径. 当python代码中, import XXX的时候, python就会遍历这些目录, 寻找ABC模块. 如果没有找到, 就会报错.

如果你在自己机器上运动前面的代码时, import shape出错, 很可能是因为sys.path中没有包含当前目录.

可以先在代码中添加:

import sys
sys.path.insert(0,'.')

模块名字

每一个模块都有自己的名字. 可以在代码中用print name 打印出模块名字

被引用的时候, 模块的名字叫做person或者shape.square
如果是直接这样运行: python shape/square.py. 模块的名字就叫做, main

目录结构:

   |-- a.py
   |-- amain.py

a.py

print __name__

a = 1

if __name__ == '__main__':
    print a

amain.py

from a import a

print a

直接运行a.py

% python a.py                                                               ✭
__main__
1

运行amain.py

% python amain.py                                                           ✭
a
1