0

プログラミングの方法で繰り返し問題が発生しており、やり方を再構築するための助けが必要です。

警告: これは長い質問です。考えられる原因を突き止めるために、エラーの性質に関する情報をできるだけ多く含めたいと思います。

TL;DR バージョン: import / includeorder により、メイン ファイルが他のファイルで定義された関数を認識できません。後でこれを防ぐためにプログラミングスタイルを改善するにはどうすればよいですか?

長いバージョン:例として Python 2.7 を使用します。main.pyファイル、および別のファイルがあるとしましょうfoo.pymain.pyにはすべてのメイン コードがあり、 でfoo.py使用されるデータを含むクラスがありますmain.py。私がしていることはfoo.py、クラス定義の直後に、同じファイルでクラスのオブジェクトを定義することです。そこでクラスをインスタンス化するだけで、そのファイルを必要とする他のファイルに簡単にインポートでき、オブジェクトはすぐに使用できるように既に存在します。ある時点でクラスをインスタンス化することをいじったり、クラスのインスタンス化の前に何かが実際に定義される前にそれを必要とするかどうかを心配したりする必要はありません。

問題は、別のファイルで定義された別のクラスでそれを行うまで、これが正常に機能することです。一度インポートしても、インタープリターは 2 番目のクラスのオブジェクトを見つけることができませんmain.py(したがって、これは、複数のインポートに起因する重複オブジェクトの問題ではないようです)。したがって、本質的に、のクラス オブジェクトmain.pyは表示されfoo.pyますが、たとえばbar.pyのオブジェクトは表示されません。

私は通常、1 つのメイン ファイルと、データおよびそのデータの使用と処理を定義するその他のファイルを持つようにプロジェクトをセットアップします。メイン ファイルは、プログラム全体で他の関数やメソッドを呼び出すことによってボールを転がす 1 つの関数またはメソッドを呼び出します。メソッドを呼び出しているクラスのデータだけをインポートし、メイン ファイルで使用されるデータを含むファイルに、特定のファイルが必要とする他のすべてのものをインポートします。メモリ効率の良いプログラムを作成する場合、これは当然のことのように思えますが、大きなプログラムでは機能しないように見えるため、私のやり方には明らかに何か問題があります。

(a. ファイル階層の設定方法、(b. インポートの設定方法、c. 発生するエラーの種類の例:

main.py:

import foo
import bar

print foo.bar
print bat.bar

foo.py:

class Foo:
  def __init__(self):
    bar = 5

foo = Foo()

bar.py:

class Bar:
  def __init__(self):
    bar = "Hello"

bat = Bar()

そして、このプログラムを実行したときに表示されるエラーは次のとおりです。

Traceback (most recent call last):
  File "C:\Users\User\Desktop\main.py", line 4, in <module>
    print foo.bar
AttributeError: 'module' object has no attribute 'bar'

main.py を次のように変更すると:

from foo import *
from bar import *

print foo.bar
print bat.bar

別のエラーが発生します。

Traceback (most recent call last):
  File "C:\Users\User\Desktop\main.py", line 4, in <module>
    print foo.bar
AttributeError: Foo instance has no attribute 'bar'

インポートの使用方法を誤解していますか? 一歩下がってmain.py次のようにすると:

from foo import *
from bar import *

foo = Foo()
bat = Bar()

print foo.bar
print bat.bar

他のファイルのクラスのインスタンス化をコメントアウトしているときに、同じエラーが発生します: Foo instance has no attribute 'bar'.

どうしてこれなの?

これは Python だけでなく、C++ でも起こります。そのため、ここで問題となるのは私のプログラミング スタイルであり、構文上の問題ではない可能性があります。

4

1 に答える 1

3

import XXそのモジュールで定義された名前を含むオブジェクトを現在の名前空間に作成します。これは、名前空間に単一の名前を追加するだけです。したがって、最初の例では、

import foo
import bar

クラス( としてアクセス可能) とオブジェクト( としてアクセス可能)fooを含むモジュール オブジェクトを作成します。同様に、クラスとオブジェクトがあります。特に、モジュールのトップレベルで呼び出される変数がないため、存在しません。Foofoo.Foofoofoo.foobarbar.Barbar.batbarfoofoo.bar

from X import YYモジュールから一致するすべてのものXを名前空間に直接インポートします。これにより、現在の名前空間に一連の名前が作成される可能性があります。そう、

from foo import *

名前Foo(クラスを参照) とfoo(のインスタンスを参照) の両方を作成しますFoo。後者の場合、fooは class のインスタンスを参照するFooので、なぜうまくいかないfoo.barのでしょうか?

まあ、実際には を定義していませんfoo.bar。コード

def __init__(self):
    bar = 5

value で呼び出されるローカル変数を定義します。クラスインスタンスには何も保存されません! あなたは書かなければならないでしょうbar5

def __init__(self):
    self.bar = 5

これがまったく機能するようにします。

C++ で同様の問題が発生している場合は、速度を落として、一度に 1 つの言語だけに集中することをお勧めします。長期的には混乱するだけなので、両方を同時に学習しようとする正当な理由はありません。他の言語を学ぶ前に、1 つの言語 (個人的には Python をお勧めします) をしっかりと理解してください。

于 2013-09-11T03:43:44.677 に答える