2009-08-27 8 views
9

私が間違っていることは何でも、それはおそらく盲目的に明らかだと思いますが、私はそれを理解することはできません。私はパッケージのチュートリアルのセクションを読んで再読しました。私が理解できるのは、これを直接実行しているので動作しないということだけです。ここでPythonパッケージ?

eulerproject/ 
    __init__.py 
    euler1.py 
    euler2.py 
    ... 
    eulern.py 
    tests/ 
    __init__.py 
    testeulern.py 

は(私が書いた最初のテストモジュール)testeuler12.pyの内容は以下のとおりです:

import unittest 
from .. import euler12 

class Euler12UnitTests(unittest.TestCase): 


    def testtriangle(self): 
     """ 
     Ensure that the triangle number generator returns the first 10 
     triangle numbers. 

     """ 
     self.seq = [1,3,6,10,15,21,28,36,45,55] 
     self.generator = euler12.trianglegenerator() 
     self.results = [] 
     while len(self.results) != 10: 
      self.results.append(self.generator.next()) 
     self.assertEqual(self.seq, self.results) 

    def testdivisors(self): 
     """ 
     Ensure that the divisors function can properly factor the number 28. 

     """ 
     self.number = 28 
     self.answer = [1,2,4,7,14,28] 
     self.assertEqual(self.answer, euler12.divisors(self.number)) 


if __name__ == '__main__': 

    unittest.main() 

私はIDLEから、コマンドからこれを実行すると、今ここで、ディレクトリの設定です行ディレクトリに、私は次のエラーを取得しながら、:

Traceback (most recent call last): 
    File "C:\Documents and Settings\jbennet\My Documents\Python\eulerproject\tests\testeuler12.py", line 2, in <module> 
    from .. import euler12 
ValueError: Attempted relative import in non-package 

私はこの問題は、以来、私は相対的な輸入を行うことができない、それを直接実行している(なぜなら__name__変化、そして私の漠然としてるということだと思いますパッケージの説明を理解することは、__name__がどのパッケージに含まれているかを示す方法の一部ですが、その場合は、テストコードから1レベル上に格納された「プロダクション」コードをインポートする方法について何をお勧めしますか?

+0

だけで選択を行うことができますコードサンプルボタンをクリックします。あるいは '' –

答えて

8

通常、あなたのディレクトリ名はパッケージ名で、PYTHONPATHのどこかにあります。たとえば:

eulerproject/ 
    euler/ 
     __init__.py 
     euler1.py 
     ... 
     tests/ 
      ... 
    setup.py 

その後、あなたは、このシステム全体をインストールするか、スクリプトを呼び出すときにPYTHONPATH=/path/to/eulerproject/:$PYTHONPATHを設定してくださいすることができます。このような

絶対インポートは、その後に動作します:

from euler import euler1 

編集

Pythonのドキュメントによると、「Pythonアプリケーションのメインモジュールとして使用することを意図したモジュールは、常に使用する必要があります絶対輸入。 (Citenoseなどのテストハーネスは、コマンドラインからパッケージを実行するのではなく、パッケージをインポートするため、他の答えに記載されているように動作します。

あなたが手で物事をしたい場合は、あなたの実行可能なスクリプトは次のように、パッケージ階層の外にする必要があります:今すぐ

eulerproject/ 
    runtests.py 
    euler/ 
     __init__.py 
     euler1.py 
     ... 
     tests/ 
      __init__.py 
      testeulern.py 

runtests.pyfrom euler.tests.testeulern import TestCaseを行うと、testeulern.pyできfrom .. import euler1

+2

ありがとう、しかしあなたのプロジェクトはもう相対的な輸入を利用していません。相対的なインポートに関する素晴らしいことは、あなたのパッケージを自己完結型にすることです。これは、メインフォルダ名に依存せず、PYTHONPATHのどこかに埋め込まれた、古いバージョンのパッケージなどからユニットを誤ってインポートすることはできません。 –

+0

さて、スクリプトを呼び出す前にPYTHONPATHを設定するにはどうすればよいですか?私が同じコンピュータ上の2つの異なる場所からこれを実行できるようにしたいのですか? ps:私は水銀でクローニング/マージを処理する方法も学んでいるので、それは2つの場所にあります。 – Jonathanb

+0

モジュールをパッケージ階層外にあるスクリプトからインポートした場合の相対インポートの動作に関する注意を追加しました。それ以外の場合は、テストハーネスを使用してください。 環境変数の設定は、作業しているものによって異なります。bashを使用している場合は、PYTHONPATH = foo python scriptname.py –

10

私は同じ問題を抱えていました。私は今、noseを使ってテストを実行し、相対インポートは正しく処理されます。

ええ、この全体的なインポートのことは混乱しています。

+2

で包み込みます。私が相対的なインポートでやろうとしてきたことを私にさせるために、私は他の答えを受け入れています。しかし、私は自分のテストハーネスとして使用するために鼻をダウンロードしています。それは、私が自分で一緒にクルージングできるものよりはるかに強力です。 – Jonathanb

+0

ちょうど私が探していたもの、 – Copperfield

関連する問題