8

1 つの方法は、"from" キーワードを使用せずに import x を使用することです。そのため、どこでも名前空間を持つものを参照します。

他に方法はありますか?C++ ifnotdef __b__ def __b__ のようなことをするようなものですか?

4

3 に答える 3

11

相互に依存するモジュールのペアを単一のモジュールにマージします。次に、追加のモジュールを導入して古い名前を取り戻します。

例えば、

# a.py
from b import B

class A: whatever

# b.py
from a import A

class B: whatever

になる

# common.py
class A: whatever
class B: whatever

# a.py
from common import A

# b.py
from common import B
于 2012-12-13T20:13:38.030 に答える
5

循環インポートは「コードの臭い」であり、多くの場合(常にではありませんが)、何らかのリファクタリングが適切であることを示しています。たとえば、A.xを使用B.yしてB.y使用する場合は、独自のモジュールに A.z移動することを検討してください。A.z

循環インポートが必要だと思われる場合は、通常、モジュールをインポートして、完全修飾名のオブジェクトを参照することをお勧めします(つまり、ではなくimport Auseを使用します)。A.xfrom A import x

于 2012-12-13T20:20:29.410 に答える
1

しようとしている場合from A import *、答えは非常に簡単です。それをしないでください。通常は、修飾名を実行して参照することになっています。import A

クイック & ダーティ スクリプトと対話型セッションの場合、これは完全に合理的なことですが、そのような場合、循環インポートに遭遇することはありません。

import *実際のコードで実行することが理にかなっている場合がいくつかあります。たとえば、複雑なモジュール構造、動的に生成するモジュール構造、またはバージョン間で頻繁に変更されるモジュール構造を非表示にする場合、またはネストが深すぎる他の誰かのパッケージをラップする場合はimport *、「ラッパー モジュール" またはトップレベルのパッケージ モジュールです。しかしその場合、あなたが輸入するものはあなたを輸入することにはなりません。

import *実際、が保証され、循環依存が発生する可能性さえあるケースを想像するのに苦労しています。

を実行している場合、それfrom A import fooを回避する方法があります (たとえば、import Athen foo = A.foo)。しかし、あなたはおそらくそれをしたくないでしょう。繰り返しますが、名前空間に本当に持ち込む必要があるかどうかを検討fooしてください。修飾名は機能であり、回避する問題ではありません。

from A import foo関数を実装する際に便宜上 を実行している場合Aは、実際にlong_package_name.really_long_module_nameは へのすべての呼び出しのためにコードが判読できないため、修飾された呼び出しをいつでも使用long_package_name.really_long_module_name.long_class_name.class_method_that_puts_me_over_80_charactersできることを覚えておいてください。import long_package_name.really_long_module_name as PP

from(また、実装の便宜上、誰かがインタラクティブ セッションから を実行し__all__た場合に、インポートされた名前が名前空間の一部として表示されないように、必ず a を指定する必要があることを覚えておいてください。)import *

また、他の人が指摘しているように、すべてではありませんがほとんどの場合、循環依存関係は設計が悪いことの兆候であり、賢明な方法でモジュールをリファクタリングすることで修正されます。また、名前を名前空間に入れる必要があり、モジュールの循環セットが実際に最適な設計であるというまれなケースでは、何らかの人為的なリファクタリングがfoo = A.foo.

于 2012-12-13T20:33:35.817 に答える