34

次のディレクトリ構造があります。

my_program/
       foo.py
       __init__.py # empty
       conf/
          config.cfg
          __init__.py 

foo.py には次のものがあります。

import sys 
#sys.path.append('conf/')
import ConfigParser

config = ConfigParser.ConfigParser()
config.read( 'conf/config.cfg' )

conf/__init__.pyが持っている

__all__ = ["config.cfg"]

このエラーはfoo.py、完全なパスを指定することで修正できますが、配置しただけではconf/config.cfgなく、相対パスを機能させたいという点で発生します。

ConfigParser.NoSectionError

これは、実際にはファイルをロードできないことを意味します (そのため、セクションを読み取ることができません)。

コメント/コメント解除を試みましsys.path.append('conf/')foo.pyが、何もしません。

何か案は?

4

3 に答える 3

56

パスは、通常はプログラムを実行するディレクトリである現在の作業ディレクトリからの相対パスです (ただし、現在のディレクトリはプログラム [またはモジュール] によって変更される可能性があり、通常はプログラム ファイルのディレクトリではありません)。

__file__解決策は、Python インタープリターが で作成する変数を使用して、ファイルへのパスを自動的に計算することfoo.pyです。

import os
config.read(os.path.join(os.path.dirname(__file__), 'conf', 'config.cfg'))

説明:__file__各プログラム(モジュール)の変数には、そのパスが含まれています(おそらく、ロードされたときの現在のディレクトリに関連しています。おそらく、Pythonドキュメントで決定的なものを見つけることができませんでした。これは、たとえばfoo.py、独自のモジュールからインポートされたときに発生しますディレクトリ)。

このようにして、現在の作業ディレクトリに関係なく、パッケージをどこに置いても、インポートは正しく機能します。

PS:補足:__all__ = ["config.cfg"]あなたが望むものではありません:あなたがするときにどのシンボル(変数、関数)をインポートするかをPythonに伝えますfrom conf import *。削除する必要があります。

PPS: 構成読み取りモジュールがロードされてから構成ファイルが読み取られるまでの間にコードが現在の作業ディレクトリを変更する場合、現在のディレクトリを変更する前に、まず構成ファイルの絶対パスを (を使用してos.path.abspath())保存する必要があります。 、現在のディレクトリが変更された後でも構成が見つかるようにします。

于 2012-12-10T12:04:20.803 に答える