2

numpy2 つの異なる方法でライブラリをインポートしました。from numpy.random import mtrandをいじった後の最初と2回目sys.path

ただし、これら 2 つのモジュール インポートの出力はまったく異なります。

>>> from numpy.random import mtrand
>>> dir(mtrand)
['RandomState', '__builtins__', '__doc__', '__file__', '__name__', '__package__', '__test__', '_rand', 'beta', 'binomial', 'bytes', 'chisquare', 'dirichlet', 'exponential', 'f', 'gamma', 'geometric', 'get_state', 'gumbel', 'hypergeometric', 'laplace', 'logistic', 'lognormal', 'logseries', 'multinomial', 'multivariate_normal', 'negative_binomial', 'noncentral_chisquare', 'noncentral_f', 'normal', 'np', 'pareto', 'permutation', 'poisson', 'power', 'rand', 'randint', 'randn', 'random_integers', 'random_sample', 'rayleigh', 'seed', 'set_state', 'shuffle', 'standard_cauchy', 'standard_exponential', 'standard_gamma', 'standard_normal', 'standard_t', 'triangular', 'uniform', 'vonmises', 'wald', 'weibull', 'zipf']

そして2番目のもの:

>>> sys.path.insert(0, '/usr/lib/pymodules/python2.7/numpy/random')
>>> import mtrand
>>> dir(mtrand)
['__builtins__', '__doc__', '__file__', '__name__', '__package__']

この動作はどのように可能ですか?

編集:

  • これら 2 つのテストは、異なる Python プロセスで実行されました。
  • システムパスをいじるのはばかげていることはわかっています。しかし、これは通常のプログラム用ではなく、オートコンプリート用です。確かに、numpy パッケージ全体をインポートしたくありません。私はちょうど作ることができるようにしたいですdir(mtrand)
4

3 に答える 3

2

拡張モジュール (つまり、共有ライブラリからロードされたモジュール) を 2 回インポートしようとすると、未定義の動作が発生します。のドキュメントからの引用reload():

ただし、多くの場合、拡張モジュールは複数回初期化されるように設計されておらず、リロード時に任意の方法で失敗する可能性があります。

ちなみに、これは私のインストールではうまくいきますnumpy

>>> from numpy.random import mtrand
>>> dir(mtrand)
['RandomState', '__builtins__', '__doc__', '__file__', '__name__', '__package__', '__test__', '_rand', 'beta', 'binomial', 'bytes', 'chisquare', 'dirichlet', 'exponential', 'f', 'gamma', 'geometric', 'get_state', 'gumbel', 'hypergeometric', 'laplace', 'logistic', 'lognormal', 'logseries', 'multinomial', 'multivariate_normal', 'negative_binomial', 'noncentral_chisquare', 'noncentral_f', 'normal', 'np', 'pareto', 'permutation', 'poisson', 'power', 'rand', 'randint', 'randn', 'random_integers', 'random_sample', 'rayleigh', 'seed', 'set_state', 'shuffle', 'standard_cauchy', 'standard_exponential', 'standard_gamma', 'standard_normal', 'standard_t', 'triangular', 'uniform', 'vonmises', 'wald', 'weibull', 'zipf']
>>> sys.path.append("/usr/lib/pyshared/python2.7/numpy/random")
>>> import mtrand
>>> dir(mtrand)
['RandomState', '__builtins__', '__doc__', '__file__', '__name__', '__package__', '__test__', '_rand', 'beta', 'binomial', 'bytes', 'chisquare', 'dirichlet', 'exponential', 'f', 'gamma', 'geometric', 'get_state', 'gumbel', 'hypergeometric', 'laplace', 'logistic', 'lognormal', 'logseries', 'multinomial', 'multivariate_normal', 'negative_binomial', 'noncentral_chisquare', 'noncentral_f', 'normal', 'np', 'pareto', 'permutation', 'poisson', 'power', 'rand', 'randint', 'randn', 'random_integers', 'random_sample', 'rayleigh', 'seed', 'set_state', 'shuffle', 'standard_cauchy', 'standard_exponential', 'standard_gamma', 'standard_normal', 'standard_t', 'triangular', 'uniform', 'vonmises', 'wald', 'weibull', 'zipf']

これは未定義の動作なので、何でも起こり得ます。

于 2012-04-16T22:50:51.133 に答える
0

誰かがあなたに -1 をつけた理由がわかりません。Python のインポートで私自身の問題を抱えた後、私の信念は、あなたが init .py ファイルをいじると、通常実行される initsys.path .py ファイルをバイパスしたということです。および(おそらく)pythonパッケージであり、init .pyファイルが含まれています。初期化ファイルは、そのパッケージまたは子パッケージ内の何かがインポートされるたびに、デフォルトで含まれます。ファイル ツリーのより深いレベルへのパスを指すことで、これらの init ファイルをバイパスし、パッケージの意図した動作を変更します。/usr/lib/pymodules/python2.7/numpy/usr/lib/pymodules/python2.7/numpy/random

スヴェンからの良い情報も。あなたの 2 つのインポートは、Python の同じ実行中のインスタンス内にあるとは限りませんでした。もしそうなら、スヴェンの答えは適切です。

于 2012-04-16T22:50:18.253 に答える
0

Endophage が指摘したように、sys.path. しかし、私は Python コードを実行したくなかったので、それを開始したと思います。これが c_builtin モジュールにとって大きな問題だとは思いませんでした。ただし、実際には正しいパッケージ パスが必要なモジュールがあります (さらに下の segfaults に関するコメントを参照してください)。

の回避策も実行しましたPyQt4が、これが唯一の回避策ではないことに気付きました。

sys.path.append('/usr/lib/python2.7/dist-packages/PyQt4')
try:
    import QtCore
except SystemError:
    QtCore = sys.modules['PyQt4.QtCore']
    debug.warning('Loaded a module with SystemError.') 

これには、 a をキャッチSystemErrorしてから sys.modules から使用することが含まれていました。実際、私はそのような操作の副作用について何も知らないので、これは非常にばかげています。私がテストしたようにPySide(これは別の Qt ラッパーです)、特定の状況でセグメンテーション違反が発生しました。

from PyQt4 import QtCoreそこで、次のようなモジュールを再度ロードするための、より Pythonic なソリューションを思いつきましたfrom numpy.random import random

興味深いことに、これらのモジュールをフル パスでロードするためのメモリ フットプリントは、sys.path.

于 2012-08-01T13:04:08.223 に答える