python模块引用梳理

文件组织结构:

t
├── __init__.py
├── main.py
├── t1
│   ├── A.py
│   └── __init__.py
└── t2
    ├── B.py
    └── __init__.py

A.py

def test():
    print 't.t1.A.test()'

 

B.py

def test():
    print 't.t2.B.test()'

 

 

 执行:

python t/main.py

 

 

 

问题1:

    在main.py中引用t2/B的test方法,如何写?

方式1: from xxx import xxx

from t2 import B
B.test()

这个写法很糟糕, 但能解决目前问题。糟糕的地方在于隐晦的引入t2。更好的方式是相对引用。

from .t2 import B
B.test()

但如果用 python t/main.py执行会报错,此处原因请参考。原因是相对引用默认作为包的方式才能运行。

正确执行方法(linux shell下): python -m t.main

 

这个写法也不够好!B在具体的代码行,看不出其出处。更好的方式是

from .  import t2
t2.B.test()


但运行时会报错!

AttributeError: 'module' object has no attribute 'B'

大致意思是, 模块对象没有B属性!这点从java/.net转过来的也许有一点不习惯!

pythony引入一个模块(import m) <==> 引入m/__init__.py文件,里面有啥就有啥,反之亦然。

破解方法:

    1. 不太好的方法有上一个代码例子, 即: from ... import ...

    2. 在模块的__init__.py文件中自动引入这些文件, 推荐最为最佳实践!

           此处修改 t/t2/__init__.py文件

import B

这样问题就完美结果了。总结下,最佳实践demo如下:

t/main.py

# -*- coding:utf-8 -*-
from . import t2
t2.B.test()

t/t2/__init__.py

# -*- coding:utf-8 -*-
from . import B

 

 

即:

1. 相对引用

2. 尽量引入更顶层包

3. 通过命名空间引用具体的方法或者类

4. 被引用包(子包)需要在__init__.py中声明(import)可以被外部直接访问的文件

 

 

问题2:

    在t2/B中如何引用t1/A的test方法?

t/t2/B.py

from .. import t1
t1.A.test()

同时声明A

t/t1/__init__.py

from . import A

 

 

 

转载请注明本文来源:http://www.cnblogs.com/Tommy-Yu/p/5794829.html

谢谢!

posted @ 2016-08-22 11:06  tommy.yu  阅读(3052)  评论(1编辑  收藏  举报