python package 之间的调用

python 解释器搜索package 模块过程

 模块:每一个python文件都是一个模块。

当执行import module时,解释器会根据下面的搜索路径,搜索module1.py文件。

1) 当前工作目录

2) PYTHONPATH中的目录

3) Python安装目录 (/usr/local/lib/python)

   事实上,模块搜索是在保存在sys.path这个全局变量中的目录列表中进行搜索。

package是模块的集合,每一个Package的根目录下面都应当有一个__init__.py 文件。当解释器发现目录下有这个文件时,他就会认为这是一个Package,而不是一个普通的目录。

 示例:通过两种方法来实现包机制,主要区别在于是否在 __init__.py 中写入模块导入语句

目录结构如下:

[root@dev home]# tree package_transfer/
package_transfer/
├── demo.py
├── __init__.py
├── package01
│   ├── classOne.py
│   └── __init__.py
└── package02
    ├── classTwo.py
    └── __init__.py

第一种调用方式 : __init__.py 是一个空白文件

1.在主入口文件里面调用。

classOne.py 内容如下:
from package02.classTwo import classTwo
class classOne:
    def __init__(self):
        self.name = "class one"

    def printInfo(self):
        print("i am class One!")
classTwo.py 内容如下:
class classTwo:
    def __init__(self):
        self.name = "class two"

    def printInfo(self):
        print("i am class two!")
主入口文件:demo.py 内容如下
from package01.classOne import classOne
from package02.classTwo import classTwo

if __name__ == "__main__":
    c1 = classOne()
    c1.printInfo()
    c2 = classTwo()
    c2.printInfo()

# 运行结果:
# i am class One!
# i am class two!
因为 此时的demo.py 文件和 package01,package02 在同一层目录下,因此,可以直接调用包下面的模块方法。

2.加入
classOne.py 要去调用 package02 下的文件 classTwo 里面的方法。
import os,sys
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))   #这里是把顶层目录加入到python的环境变量中。
sys.path.append(BASE_DIR)

from package02.classTwo import classTwo
class classOne:
    def __init__(self):
        self.name = "class one"

    def printInfo(self):
        print("i am class One!")


if __name__ == "__main__":

    c2 = classTwo()
    c2.printInfo()

# 运行结果:
# i am class two!

第二种调用方式:在__init__.py 下面写入包的信息。

还是上面的目录和内容:

在 packge01/__init__.py 中添加:

import sys,os
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.append(BASE_DIR)

from package01.classOne import classOne

  在 packge02/__init__.py 中添加:

import sys,os
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.append(BASE_DIR)

from package02.classTwo import classTwo

 在 demo.py 文件中就可以这样写:

import package01
import package02

if __name__ == "__main__":
    c1 = package01.classOne()
    c1.printInfo()
    c2 = package02.classTwo()
    c2.printInfo()

# 运行结果:
# i am class One!
# i am class two!

还可以这样导入:

from package01 import *
from package02 import *

if __name__ == "__main__":
    c1 = classOne()
    c1.printInfo()
    c2 = classTwo()
    c2.printInfo()

# 执行结果
# i am class One!
# i am class two!

如果不在上面的 __init__.py 文件中写入信息。如果直接导入,那么会报如下错误:

import package01
import package02

if __name__ == "__main__":
    c1 = package01.classOne()
    c1.printInfo()
    c2 = package02.classTwo()
    c2.printInfo()

# 运行结果:
# Traceback (most recent call last):
#   File "D:/gitcode/...../package_transfer/demo.py", line 21, in <module>
#     c1 = package01.classOne()
# AttributeError: module 'package01' has no attribute 'classOne'

记忆:所有的模块的引入,在__init__.py 里面的路径应该写到当前project 的顶层目录,这样在调用的时候 就能够清晰明了的导入自己想要导入的模块。

 

posted @ 2018-01-02 18:01  Nice_keep-going  阅读(1703)  评论(0编辑  收藏  举报