[英]Layout and importing for pytest in python3
我無法從pytest函數導入模塊。 我知道有100萬個問題,但我已經閱讀了一堆,但仍然難以理解。
$ tree
.
└── code
├── eight_puzzle.py
├── missionaries_and_cannibals.py
├── node.py
├── search.py
└── test
├── test_eight_puzzle.py
└── test_search.py
2 directories, 6 files
$
$ grep import code/test/test_search.py
import sys
import pytest
import code.search
$
$ pytest
...
ImportError while importing test module '~/Documents/code/test/test_search.py'.
Hint: make sure your test modules/packages have valid Python names.
Traceback:
code/test/test_search.py:14: in <module>
import code.search
E ModuleNotFoundError: No module named 'code.search'; 'code' is not a package
...
我希望那能奏效。 “代碼”是一個包,對嗎? Python 3中的軟件包是其中包含.py文件的任何目錄。
我也嘗試了相對導入- from .. import search
-並得到以下結果。
ImportError while importing test module '~/Documents/code/test/test_search.py'.
Hint: make sure your test modules/packages have valid Python names.
Traceback:
code/test/test_search.py:14: in <module>
from .. import search
E ImportError: attempted relative import with no known parent package
我也嘗試修改的sys.path如圖所示這里 ,我指定PYTHONPATH,並添加初始化代碼和測試.py文件。
我可以在不使用setuptools之類的情況下使導入工作嗎? 這只是為了進行實驗,因此我寧願不處理開銷。
可能還需要注意的是我正在使用conda,因為當我將python 2 pip安裝的pytest與init .py文件一起使用時,它似乎可以正常工作。
有關不帶__init__.py
文件的目錄的一些說明:
盡管沒有__init__.py
的目錄在Python 3中是有效的導入源,但它不是常規包,而是隱式名稱空間包(有關詳細信息,請參見PEP 420 )。 除其他屬性外,隱式名稱空間包在導入時是二等公民,這意味着當Python在sys.path
有兩個名稱相同的包時,一個是常規包,另一個是隱式命名空間包,即常規包。無論使用哪種軟件包,都將是首選。 自己檢查一下:
$ mkdir -p implicit_namespace/mypkg
$ echo -e "def spam():\n print('spam from implicit namespace package')" > implicit_namespace/mypkg/mymod.py
$ mkdir -p regular/mypkg
$ touch regular/mypkg/__init__.py
$ echo -e "def spam():\n print('spam from regular package')" > regular/mypkg/mymod.py
$ PYTHONPATH=implicit_namespace:regular python3 -c "from mypkg.mymod import spam; spam()"
這將打印spam from regular package
:雖然implicit_namespace
至上的sys.path
, mypkg.mymod
從regular
的進口,而不是因為regular/mypkg
是一個普通的包。
現在您知道了,因為您的程序包code
是隱式命名空間程序包,所以Python在遇到code
導入時將更喜歡常規的code
導入。 對於您來說不幸的是, stdlib中有一個模塊code
,因此實際上是一個“隱藏名稱”的問題:您有一個導入對象,其名稱與stdlib中的名稱相同,但不是隱藏了stdlib的導入,而是陰影了您的。
因此,您需要做兩件事才能使布局可用:
code
目錄一個唯一的名稱(對於這個答案的例子,讓它成為mycode
) sys.path
,因為它本身不在sys.path
。 您有一些可能:
conftest.py
文件添加到根目錄(除了mycode
目錄)。 這將指示pytest
將根目錄添加到sys.path
(有關說明,請參見此處 )。 現在,您可以照常運行pytest
,導入將得到解決; python -m pytest
運行測試-調用解釋器將當前目錄直接添加到sys.path
; PYTHONPATH
env var將當前目錄添加到sys.path
,例如運行PYTHONPATH=. pytest
PYTHONPATH=. pytest
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.