我似乎无法导入我自己的自定义NYT模块。我的项目结构如下,我在Mac上:
articulation/
articulation/
__init__.py # empty
lib/
nyt.py
__init__.py # empty
tests/
test_nyt.py
__init__.py # empty
当我尝试从第一个父目录运行python articulation/tests/test_nyt.py
时,我得到了
File "articulation/tests/test_nyt.py", line 5, in <module>
from articulation.lib.nyt import NYT
ImportError: No module named articulation.lib.nyt
我也试过
(venv) Ericas-MacBook-Pro:articulation edohring$ Python -m articulation/tests/test_nyt.py
/Users/edohring/Desktop/articulation/venv/bin/Python: Import by filename is not supported.
test_nyt.py
import sys
sys.path.insert(0, '../../')
import unittest
#from mock import patch
# TODO: store example as fixture and complete test
from articulation.lib.nyt import NYT
class TestNYT(unittest.TestCase):
@patch('articulation.lib.nyt.NYT.fetch')
def test_nyt(self):
print "hi"
#assert issubclass(NYT, Article)
# self.assertTrue(sour_surprise.title == '')"""
nyt.py
from __future__ import division
import regex as re
import string
import urllib2
from collections import Counter
from bs4 import BeautifulSoup
from cookielib import CookieJar
PARSER_TYPE = 'html.parser'
class NYT:
def __init__(self, title, url):
self.url = url
self.title = title
self.words = get_words(url)
def get_words(url):
cj = CookieJar()
opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cj))
p = opener.open(url)
soup = BeautifulSoup(p.read(), PARSER_TYPE)
# title = soup.html.head.title.string
letters = soup.find_all('p', class_='story-body-text story-content')
if len(letters)==0:
letters = soup.find_all('p', class_='paragraph--story')
if len(letters)==0:
letters = soup.find_all('p', class_='story-body-text', )
words = Counter()
for element in letters:
a = element.get_text().split()
for c in a:
c = ''.join(ch for ch in c if c.isalpha())
c = c.lower()
if len(c) > 0:
words[c] += 1
return words
def test_nyt():
china_apple_stores = NYT('title_test', 'http://www.nytimes.com/2016/12/29/technology/iphone-china-apple-stores.html?_r=0')
assert(len(china_apple_stores.words) > 0)
# print china_apple_stores.words
fri_brief = NYT('Russia, Syria, 2017: Your Friday Briefing', 'http://www.nytimes.com/2016/12/30/briefing/us-briefing-russia-syria-2017.html')
assert(fri_brief.title == 'Russia, Syria, 2017: Your Friday Briefing')
assert(fri_brief.url == 'http://www.nytimes.com/2016/12/30/briefing/us-briefing-russia-syria-2017.html')
assert(len(fri_brief.words) > 0)
vet = NYT('title_test', 'http://lens.blogs.nytimes.com/2017/01/03/a-love-story-and-twins-for-a-combat-veteran-amputee/')
assert(len(vet.words)>0)
print "All NYT Tests Passed"
#test_nyt()
我尝试过以下操作,似乎没有工作 - 有谁知道如何解决这个问题? - Adding an init.py file to the top directory - &gt;没有帮助 - Entering Memory Python无法找到这个 - 也许是因为我使用的是Python 2.如果这是问题,我可以发布更多我尝试过的内容。 - 在下面的建议
的顶部添加sys.path答案 0 :(得分:0)
这样做:
import sys
sys.path.insert(0, '../../')
通常是一个坏主意。有时它对你测试某些东西很有用,或者你有一个单一用途的程序,你只需要在短时间内工作然后你就会扔掉,但总的来说这是一个坏习惯,因为一旦您移动目录或将代码提供给其他人,它可能会停止工作。我建议你不要让自己养成这样做的习惯。
您遇到此类错误的最可能原因是目录/Users/edohring/Desktop/articulation
未出现在sys.path
中。要做的第一件事是看sys.path
中究竟是什么,一个好方法就是暂时将这些行放在test_nyt.py
的顶部:
import os.path, sys
for p in sys.path:
print(p)
if not os.path.isabs(p):
print(' (absolute: {})'.format(os.path.abspath(p)))
sys.exit()
然后运行
python articulation/tests/test_nyt.py
并查看输出。您将获得Python查找其模块的每个目录路径的一行,如果这些路径中的任何一个是相对的,它还将打印出相应的绝对路径,以便不会产生混淆。我怀疑你会发现/Users/edohring/Desktop/articulation
没有出现在这个列表的任何地方。
如果事实证明是这样的话,那么最简单(但最不适合未来)的方法就是运行
export PYTHONPATH=".:$PYTHONPATH"
在使用Python本身使用您的模块执行任何操作之前,在shell中(不是在Python中)。在Python启动时,PYTHONPATH
环境变量中命名的目录将添加到sys.path
。这只是一个临时修复,除非你将它放在像$HOME/.bashrc
这样的文件中,每次打开终端窗口时shell都会读取它。您可以阅读此内容和better ways to add the proper directory to sys.path
in this question。
运行脚本的更好方法可能是使用shell命令
python -m articulation.tests.test_nyt
这需要在目录/Users/edohring/Desktop/articulation
中运行,或者至少该目录需要出现在sys.path
中才能使命令生效。但是以这种方式使用-m
开关会导致Python以不同的方式处理它sys.path
的设置方式,它可能适合您。您可以阅读有关how sys.path
is populated in this answer的更多信息。