2010-10-21 126 views
1

我有一个模块导入问题。使用python 2.6在Ubuntu 10.10Python导入模块导致NameError

我有在http://www.jejik.com/articles/2007/02/a_simple_unix_linux_daemon_in_python/子类的守护进程的类。我创建了一个包含代码的模块的python包,从django项目中导入一些模型。代码在从类中使用时不起作用,而不是继承守护进程。该结构看起来是这样的:

my_module 
    __init__.py 
    - bin 
    - cfg 
    - core 
    __init__.py 
    collection.py 
    daemon.py 

的ItemRepository代码:

class ItemRepository(object): 
    """This class provides an implementation to retrieve configuration data 
    from the monocle database 
    """ 
    def __init__(self, project_path): 
     if project_path is not None: 
      sys.path.append(project_path) 

     try: 
      from django.core.management import setup_environ 
      from someproj import settings 
      setup_environ(settings) 
      from someproj.someapp.models import ItemConfiguration 
     except ImportError: 
      print "Could not import models from web app. Please ensure the\ 
      PYTHONPATH is configured properly" 

    def get_scheduled_collectors(self): 
     """This method finds and returns all ItemConfiguration objects 
     that are scheduled to run 
     """ 
     logging.info('At the error path: %s' % sys.path) 
     # query ItemConfigs from database 
     items = ItemConfiguration.objects.filter(disabled=False) #ERROR OCCURS AT THIS LINE 
     return [item for item in items if item.scheduled] 

守护程序代码(/usr/local/bin/testdaemon.py):

import sys 
from my_module.core.daemon import Daemon 
from my_module.core.collection import ItemRepository 
import logging 
import time 

class TestDaemon(Daemon): 
    default_conf = '/etc/echodaemon.conf' 
    section = 'echo' 

    def run(self): 
     while True: 
      logging.info('The echo daemon says hello') 
      ir = ItemRepository(project_path=self.project_path) 
      items = ir.get_scheduled_collectors() #TRIGGERS ERROR 
      logging.info('there are %d scheduled items' % len(items)) 
      time.sleep(1) 

if __name__ == '__main__': 
    TestDaemon().main() 

错误我得到的是“NameError:全局名称'my_module'未定义”它通过导入但在尝试调用对象的方法时失败。我假设它与sys.path/PYTHONPATH有关,但我知道我的django项目正在路径中,因为我打印出来了。目前为止,python文档或Learning Python还没有提供帮助。有没有人有任何见解或知道对模块进口的很好的参考?

UPDATE:

现在,我已经尝试简化问题,使其更容易理解。现在我有一个看起来像一个目录结构:

/home 
    /username 
    /django 
     /someproj 
     /web 
      models.py 
     /my_module 
     daemon.py 

我在/etc/bash.bashrc设置$ PYTHONPATH变量“/家/用户名/ Django的。

里面的testdaemon.py文件进口的样子:

import logging 
from django.core.management import setup_environ 
from someproj import settings 
setup_environ(settings) 
from someproj.web.models import ItemConfiguration 

但现在我得到一个ImportError:无模块名为 'someproj'。于是我追加了路径。

import sys 
sys.path.append('/home/username/django') 
import logging 
from django.core.management import setup_environ 
from someproj import settings 
setup_environ(settings) 
from someproj.web.models import ItemConfiguration 

现在ImportError说:没有名为'web'的模块。这里的回溯:

Traceback (most recent call last): 
    File "testdaemon.py", line 77, in <module> 
    TestDaemon('/tmp/testdaemon.pid').run() 
    File "testdaemon.py", line 47, in run 
    scheduled_items = [item for item in ItemConfiguration.objects.filter(disabled=False) if collector.scheduled] 
    File "/usr/local/lib/python2.6/dist-packages/django/db/models/manager.py", line 141, in filter 
    return self.get_query_set().filter(*args, **kwargs) 
    File "/usr/local/lib/python2.6/dist-packages/django/db/models/query.py", line 550, in filter 
    return self._filter_or_exclude(False, *args, **kwargs) 
    File "/usr/local/lib/python2.6/dist-packages/django/db/models/query.py", line 568, in _filter_or_exclude 
    clone.query.add_q(Q(*args, **kwargs)) 
    File "/usr/local/lib/python2.6/dist-packages/django/db/models/sql/query.py", line 1128, in add_q 
    can_reuse=used_aliases) 
    File "/usr/local/lib/python2.6/dist-packages/django/db/models/sql/query.py", line 1026, in add_filter 
    negate=negate, process_extras=process_extras) 
    File "/usr/local/lib/python2.6/dist-packages/django/db/models/sql/query.py", line 1179, in setup_joins 
    field, model, direct, m2m = opts.get_field_by_name(name) 
    File "/usr/local/lib/python2.6/dist-packages/django/db/models/options.py", line 291, in get_field_by_name 
    cache = self.init_name_map() 
    File "/usr/local/lib/python2.6/dist-packages/django/db/models/options.py", line 321, in init_name_map 
    for f, model in self.get_all_related_m2m_objects_with_model(): 
    File "/usr/local/lib/python2.6/dist-packages/django/db/models/options.py", line 396, in get_all_related_m2m_objects_with_model 
    cache = self._fill_related_many_to_many_cache() 
    File "/usr/local/lib/python2.6/dist-packages/django/db/models/options.py", line 410, in _fill_related_many_to_many_cache 
    for klass in get_models(): 
    File "/usr/local/lib/python2.6/dist-packages/django/db/models/loading.py", line 167, in get_models 
    self._populate() 
    File "/usr/local/lib/python2.6/dist-packages/django/db/models/loading.py", line 61, in _populate 
    self.load_app(app_name, True) 
    File "/usr/local/lib/python2.6/dist-packages/django/db/models/loading.py", line 76, in load_app 
    app_module = import_module(app_name) 
    File "/usr/local/lib/python2.6/dist-packages/django/utils/importlib.py", line 35, in import_module 
    __import__(name) 
ImportError: No module named web 

从早先的意见,我尝试添加那么回事:

import sys 
sys.path.append('/home/username/django') 
import logging 
from django.core.management import setup_environ 
from someproj import settings 
setup_environ(settings) 
from someproj import web 
from someproj.web import models 
from someproj.web.models import ItemConfiguration 

但是这并没有帮助。所以我创建了一个非常简单的文件:

#!/usr/bin/python 

import logging 
import time 
import sys 
sys.path.append('/home/username/django') 
from django.core.management import setup_environ 
from someproj import settings 
setup_environ(settings) 
from someproj.web.models import ItemConfiguration 

if __name__ == '__main__':  
    print sys.path 
    items = ItemConfiguration.objects.all() 
    for item in items: 
     print item 

这个工程!这只会让我更加困惑。所以现在我想也许它与守护进程有关。它使用os.fork(),我不知道路径是否仍然设置。这就是为什么我在/etc/bash.bashrc文件中设置$ PYTHONPATH变量的原因。

还有什么见解吗?我真的需要守护进程,因为我需要一个漫长的运行过程,所以我没有太多的选择。

+2

您应该显示* actual * traceback,它会显示错误发生的位置。 – 2010-10-22 08:06:33

回答

0

最后,我需要在INSTALLED_APPS设置的Django项目settings.py文件中引用我的应用程序的完全限定名。 “someproj.web”而不是“web”。使用较短的版本在Django项目中工作正常,但从外部来看不太好。

0

使用from my_module.core.daemon import Daemon您实际上并未将加载的模块my_module绑定到变量。在您的其他进口之前或之后使用import my_module 来做到这一点。

解释代码:

>>> from xml import dom 
>>> xml 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
NameError: name 'xml' is not defined 
>>> import xml 
>>> xml 
<module 'xml' from '/usr/lib/python2.6/xml/__init__.pyc'> 
+0

需要更多字符 – RyanBrady 2010-10-21 21:59:50

+0

我添加了导入my_module并将my_module.core.collection导入到守护进程中的导入中,没有任何更改。 – RyanBrady 2010-10-21 22:31:25

0

你让我困惑你是什么意思“Django项目”是你的模块“my_module”是一个更高的包的一部分?像这样

django_project 
    | 
    |my_module 
     __init__.py 
     - bin 
     - cfg 
     - core 
      __init__.py 
      collection.py 
      daemon.py 

如果是这样,如果像你说的django_project在PYTHONPATH,所以你只要导入my_module是这样的:通过它的最好导入模块没课的方式

from django_project.my_module.core.daemon import Daemon 

既不功能是这样的:

from django_project.my_module.core import daemon 

,并使用它像这样:

daemon.Daemon() 
+0

django应用程序在/ home/django/someproj中。 my_module是独立的,并通过distutils进行安装。 – RyanBrady 2010-10-21 22:33:23

+0

@RJBrady:我想我现在明白了,这不是导入失败,导入没问题,因为如果失败,他会提示的错误是“无模块名称模块”,但相反,您有一个错误“NameError:global名称'my_module'未定义“当使用变量并且没有声明之前会引发此错误,因此我建议您在程序包模块中搜索单词”my_module“或仅使用调试器(如pdb)来查看它何时发生失败,我希望这会帮助你:) – mouad 2010-10-21 22:52:23

+0

是啊,我在发布StackOverflow之前去了pdb路由。你碰到了头 - 我感到困惑的是,如果我在构造函数中导入并且没有导入ImportError,为什么它稍后会给我一个NameError?如果它没有被导入,我应该在我打电话之前知道... – RyanBrady 2010-10-21 23:53:05