Python的路徑引用


1、以HOME目錄為准,進行跳轉

sys.path.append(os.path.dirname(__file__) + os.sep + '../')

from config import swordfishconf
from utils  import log
from utils.mysql_base import MySQLBase

將程序的HOME目錄添加到sys.path中,然后以此為准,進行跳轉。
例子中對於封裝的MySQLBase類訪問是先訪問utils包,然后從mysql_base.py中找到MySQLBase類

缺點:查看代碼的時候當前腳本和包的關系不十分明了,需要調到HOME,然后再從HOME進行逐個查找

問題:如何直接看出當前腳本和包的關系,而不是經過HOME

2、使用absolute_path

配置PYTHONPATH:

export PYTHONPATH=/data1/guosong/opdir/20141017/test:$PYTHONPATH

代碼示例:

.
|-- __init__.py
|-- lib
|   |-- __init__.py
|   |-- pack1
|   |   |-- __init__.py
|   |   |-- a.py
|   |   `-- aa.py
|   `-- pack2
|       |-- __init__.py
|       |-- b.py
|-- test.py

test.py的代碼如下:

[root@typhoeus79 ice_test_m test]# more test.py
#!/usr/bin/env python2.7
#-*- coding:utf8 -*-

from __future__ import absolute_import

from lib.pack1.a import AObject

if __name__ == '__main__':
    AObject.printword()

從lib.pack1.a中引用類AObject,調用它的靜態方法

a.py內容:

[root@typhoeus79 ice_test_m pack1]# more a.py
#!/usr/bin/env python2.7
#-* coding:utf8 -*-
from __future__ import absolute_import

#from .a import BObject
from ..pack2.b import BObject

class AObject(object):

    @classmethod
    def printword(self):
        b = BObject('a call b class')

a.py中又調用上一次目錄pack2.b中的BObject

b.py內容為:

[root@typhoeus79 ice_test_m pack2]# more b.py
#!/usr/bin/env python2.7
#-* coding:utf8 -*-
#from __future__ import absolute_import

class BObject(object):
    def __init__(self,bstr):
        print "B:%s" % bstr

 

好處:不用再經過HOME,直接根據相對路徑進行跳轉

3、absolute_path介紹

 

4、使用absolute_path遇到的問題

4.1、ValueError: Attempted relative import in non-package

包含相對路徑import 的python腳本不能直接運行,只能作為module被引用。原因正如手冊中描述的,所謂相對路徑其實就是相對於當前module的路徑,但如果直接執行腳本,這個module的name就是“__main__”, 而不是module原來的name, 這樣相對路徑也就不是原來的相對路徑了,導入就會失敗,出現錯誤“ValueError: Attempted relative import in non-package”

Note that both explicit and implicit relative imports are based on the name of the current module. Since the name of the main module is always"__main__", modules intended for use as the main module of a Python application should always use absolute imports.

在使用相對引用的文件中,不能有__main__方法,只執行作為一個module進行引用,而不是直接執行腳本。


4.2、 ValueError: Attempted relative import beyond toplevel package

test.py內容:

[root@typhoeus79 ice_test_m test]# more test.py
#!/usr/bin/env python2.7
#-*- coding:utf8 -*-

from __future__ import absolute_import


from pack1.a import AObject
from pack1.a import now

if __name__ == '__main__':
    AObject.printword()
    print now

其他均不變,但是將pack2和pack1的包遷移到外面出

.
|-- __init__.py
|-- lib
|   |-- __init__.py
|-- pack1
|   |-- __init__.py
|   |-- a.py
|   `-- aa.py
|-- pack2
|   |-- __init__.py
|   |-- b.py
|-- test.py

運行test.py出錯:

[root@typhoeus79 ice_test_m test]# ./test.py 
Traceback (most recent call last):
  File "./test.py", line 7, in <module>
    from pack1.a import AObject
  File "/data1/guosong/opdir/20141017/test/pack1/a.py", line 6, in <module>
    from ..pack2.b import BObject
ValueError: Attempted relative import beyond toplevel package

  

處理方式是創建一個lib目錄,將pack1和pack2拉到lib下面,修改test.py中的路徑然后就ok了。


 

【參考資料】

1、http://blog.csdn.net/chinaren0001/article/details/7338041

2、http://hi.baidu.com/fleago/item/06b5c95765b17e12aaf6d79b


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM