1

モジュールのインポートに問題があります。

Ubuntu10.10でPython2.6を使用する

http://www.jejik.com/articles/2007/02/a_simple_unix_linux_daemon_in_python/にデーモンをサブクラス化するクラスがあります。djangoプロジェクトからいくつかのモデルをインポートするコードを含むモジュールを使用してPythonパッケージを作成しました。このコードは、デーモンをサブクラス化するのではなく、クラスから使用した場合に機能します。構造は次のようになります。

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ドキュメントやLearningPythonのこれまでのところ、何も役に立ちませんでした。誰かがモジュールのインポートへの洞察や良いリファレンスを知っていますか?

アップデート:

今、私は問題を単純化して理解しやすくしようと試みました。これで、次のようなディレクトリ構造になりました。

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

/etc/bash.bashrcの$PYTHONPATH変数を「/home/ username/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変数を設定した理由です。

これ以上の洞察はありますか?私は本当にデーモンが必要です。長時間実行されるプロセスが必要なため、選択肢はあまりありません。

4

3 に答える 3

0

結局、INSTALLED_APPS設定のDjangoプロジェクトのsettings.pyファイルでアプリの完全修飾名を参照する必要がありました。「web」だけでなく「someproj.web」。短いバージョンを使用すると、Djangoプロジェクト内では問題なく機能しますが、外部からはあまりうまく機能しません。

于 2010-11-08T19:36:47.470 に答える
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'>
于 2010-10-21T21:42:27.773 に答える
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()
于 2010-10-21T22:01:17.557 に答える