2010-10-21 125 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