2014-09-01 10 views
2

我是一位令人困惑的Python愛好者。我發佈了What else can I do to troubleshoot a package not importing in python yet imports in ipython while in a virtualenv?,認爲我的virtualenv存在問題。更多的故障排除表明這可能並非如此。將軟件包添加到sys.path的腳本從ipython運行時按預期導入,但在腳本從python運行時拋出異常

我會很感激任何見解或疑難解答提示,以便我可以繼續開發包。先謝謝你!與Python我的Ubuntu 14.04.1 LTS系統上的問題

簡介2.7.6:

  1. 我有一個名爲test_dummy.py腳本,將包路徑sys.path中,然後嘗試導入包。
  2. 腳本以run test_dummy.pyipython內運行時,程序包無錯地導入。
  3. 當腳本以python test_dummy.py運行時,某些程序包將引發ImportError異常。
  4. 最令人沮喪的是,包含代碼的軟件包不止是一個__init__.py文件導入。只有__init__.py文件的簡單測試包不會按預期導入。我無法確定是什麼原因導致最簡單的軟件包在從python調用腳本(即python test_dummy.py)時在導入時拋出異常。

我的PWD是這樣的:

. 
├── browser 
├── display 
├── hello_world 
├── singleton 
├── test_a 
└── tests 

test_a是這樣的:

test_a 
├── __init__.py 
└── __init__.pyc 

程序hello_world是這樣的:

hello_world/ 
├── hello.py 
├── hello.pyc 
├── __init__.py 
└── __init__.pyc 

hello.py是這樣的:

HELLO = 'Hello, world!' 
print HELLO 

其他軟件包['browser','display','singleton']全部包含init .py文件和其他運行時不會引發已知異常的代碼。

測試是這樣:

tests 
└── test_dummy.py 

在test_dummy的代碼。潘岳:

import importlib 
import os 
import sys 
HOME = os.path.expanduser('~') 
PYTHON = os.path.join(HOME, 'development/my_python') 
PACKAGES = [ 
    'browser', 
    'display', 
    'singleton', 
    'test_a', 
    'hello_world', 
] 
MODULES = [ 
    '', 
    '', 
    '', 
    '', 
    'hello', 
] 
IMPORTS = ['.'.join((pkg, module)).strip('.') 
      for pkg, module 
      in zip(PACKAGES, MODULES)] 
""" 
append sys.path with PACKAGES if package exists and not already 
in the sys.path 
""" 
for package in PACKAGES: 
    package = os.path.join(PYTHON, package) 
    if os.path.exists(package) is True: 
     if package not in sys.path: 
      print "loading package '{0}'".format(package) 
      sys.path.append(package) 
     else: 
      print "package '{0}' already in sys.path".format(package) 
    else: 
     message = "Package '{0}' does not exist.".format(package) 
     raise IOError(message) 
""" 
import IMPORTS if the package is in sys.path 
""" 
for item in IMPORTS: 
    pkg_in_path = [pkg == os.path.basename(path) 
        for pkg in PACKAGES for path in sys.path] 
    if any(pkg_in_path): 
     print "loading '{0}'".format(item) 
     importlib.import_module(item) 
    else: 
     raise AttributeError("{0} not in sys.path".format(item)) 

IPython的結果:

$ ipython 
# result 
Python 2.7.6 (default, Mar 22 2014, 22:57:26) 
Type "copyright", "credits" or "license" for more information. 

IPython 2.2.0 -- An enhanced Interactive Python. 
?   -> Introduction and overview of IPython's features. 
%quickref -> Quick reference. 
help  -> Python's own help system. 
object? -> Details about 'object', use 'object??' for extra details. 
Warning: disable autoreload in ipython_config.py to improve performance. 

In [3]: run tests/test_dummy.py 
loading package '/home/dmmmd/development/my_python/browser' 
loading package '/home/dmmmd/development/my_python/display' 
loading package '/home/dmmmd/development/my_python/singleton' 
loading package '/home/dmmmd/development/my_python/test_a' 
loading package '/home/dmmmd/development/my_python/hello_world' 
loading 'browser' 
loading 'display' 
loading 'singleton' 
loading 'test_a' 
loading 'hello_world.hello' 
Hello, world! 

結果從python tests/test_dummy.py

loading package '/home/dmmmd/development/my_python/browser' 
loading package '/home/dmmmd/development/my_python/display' 
loading package '/home/dmmmd/development/my_python/singleton' 
loading package '/home/dmmmd/development/my_python/test_a' 
loading package '/home/dmmmd/development/my_python/hello_world' 
loading 'browser' 
loading 'display' 
loading 'singleton' 
loading 'test_a' 
Traceback (most recent call last): 
    File "tests/test_dummy.py", line 46, in <module> 
    importlib.import_module(item) 
    File "/usr/lib/python2.7/importlib/__init__.py", line 37, in import_module 
    __import__(name) 
ImportError: No module named test_a 

導入在Python解釋器包 'test_a' 不拋出異常:

Python 2.7.6 (default, Mar 22 2014, 22:57:26) 
[GCC 4.8.2] on linux2 
Type "help", "copyright", "credits" or "license" for more information. 
>>> import sys 
>>> sys.path.append('/home/dmmmd/development/my_python/test_a') 
>>> import test_a 
>>> print test_a 
<module 'test_a' from 'test_a/__init__.pyc'> 
>>> 
+0

如何'__init __ py'在'test_a'長相?並在'瀏覽器'? – 2014-09-01 13:12:00

+0

瀏覽器/ __ init__.py包含一條評論和'從瀏覽器導入Firefox'。在test_a中,__init__.py是空的。 – DMfll 2014-09-01 13:13:26

+0

我不知道是什麼問題,您是否嘗試向'test_a'添加一些代碼或將'browser'文件夾名稱更改爲'test_a'並查看它是否已導入? – 2014-09-01 13:51:46

回答

0

我找到了解決方案雖然解決方案沒有解決爲什麼某些包路徑中添加的問題的特設當腳本與python test_dummy.py運行不會導入時尚sys.path

我最初在嘗試使用py.test時遇到了這個問題。 In the py.test documentation I saw this tip關於「用virutalenv,pip和可編輯模式管理您的項目」。我沒有理會它,因爲我認爲它對於我的Python知識水平來說太過先進。

我決定在閱讀關於「creating your own python project」後嘗試提示。

在我創建了一個setup.py文件用下面的代碼的PWD:

from setuptools import setup, find_packages 

setup(name='import_troubleshooting', version='1.0') 
packages = find_packages(exclude=[ 
    'my_django', 
    'fake*', 
    'tests*' 
]) 

我然後執行在命令行以下代碼:

pip install -e . # the pip way (which just calls "setup.py develop") 

我然後與執行以下代碼預期結果:

$ python tests/test_dummy.py 
# output  
package '/home/dmmmd/development/my_python/browser' already in sys.path 
package '/home/dmmmd/development/my_python/display' already in sys.path 
package '/home/dmmmd/development/my_python/singleton' already in sys.path 
loading package '/home/dmmmd/development/my_python/test_a' 
loading package '/home/dmmmd/development/my_python/hello_world' 
loading 'browser' 
loading 'display' 
loading 'singleton' 
loading 'test_a' 
loading 'hello_world.hello' 
Hello, world! 

這些都不能解釋爲什麼我無法在專用時尚中添加包路徑,而無需先用pip install -e .安裝我的包。奇怪的是,只有在將腳本傳遞給python時,失敗纔是。 ipython test_dummy.py工程沒有安裝我的本地軟件包第一

但是,我很高興能夠學到有關python安裝和包裝的知識。當從python tests/test_dummy.py調用時,test_dummy.py腳本現在按預期運行。

我現在困惑,爲什麼當test_dummy.py腳本運行三個程序包已經在sys.path

package '/home/dmmmd/development/my_python/browser' already in sys.path 
package '/home/dmmmd/development/my_python/display' already in sys.path 
package '/home/dmmmd/development/my_python/singleton' already in sys.path 

我不記得做任何事情,會增加那些sys.path但有可能因爲我一直在做各種教程。在我沒有運行我創建的setup.py的任何其他環境中,它們不在sys.path中。

我的困惑是Python複雜性的一個症狀,不是原因!

謝謝大家的意見。

注:這是python test_dummy.py新的virtualenv後的輸出:

$ pip install -e . 
# install output unremarkable 
$ python tests/test_dummy.py 
# output 
    loading package '/home/dmmmd/development/my_python/automated_browsing/browser' 
loading package '/home/dmmmd/development/my_python/automated_browsing/display' 
loading package '/home/dmmmd/development/my_python/automated_browsing/singleton' 
loading package '/home/dmmmd/development/my_python/automated_browsing/hello_world' 
loading package '/home/dmmmd/development/my_python/automated_browsing/test_a' 
loading 'browser' 
loading 'display' 
loading 'singleton' 
loading 'hello_world.hello' 
Hello, world! 
loading 'test_a'