2012-04-16 206 views
2

我用兩種不同的方式導入了numpy庫。第一次與from numpy.random import mtrand和第二次後與sys.path搞亂。Python導入內部差異

然而,這兩個模塊導入的輸出是完全不同的:

>>> 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.insert(0, '/usr/lib/pymodules/python2.7/numpy/random') 
>>> import mtrand 
>>> dir(mtrand) 
['__builtins__', '__doc__', '__file__', '__name__', '__package__'] 

這是怎麼可能的行爲?

編輯:

  • 這兩個試驗是在不同的Python進程執行。
  • 與系統路徑混淆是愚蠢的,我知道。但這不是一個正常的程序,而是一個自動完成的程序。我當然不想導入整個numpy包。我只是想能夠做一個dir(mtrand)
+0

這讓我覺得自動補全的方法不對。 ([始終將問題的實際目標從一開始就包括在內。](http://meta.stackexchange.com/questions/66377/what-is-the-xy-problem))如果沒有,也不能導入'mtrand'導入NumPy - 對我來說,你的第二種方法也是「有效」,但將所有的Nu​​mPy都引入到'sys.modules'中,就像正常導入一樣。 – 2012-04-17 12:54:34

+0

你應該從標準庫[IPython的增強版本](http://docs.python.org/library/rlcompleter.html)看看['rlcompleter'] //ipython.org/ipython-doc/stable/api/generated/IPython.core.completer.html)和[rope's](http://rope.sourceforge.net/)自動完成。後者是最先進的。 – 2012-04-17 12:54:45

+0

rlcompleter和IPython非常簡單。繩是唯一真正的自動完成。但它從來沒有爲我工作 - 所以我決定更好地解決問題(所有其他解決方案都是簡單的 - > python-omnicomplete,或者不是免費的 - > pycharm)。它已經工作得很好,但是內建的仍然是一個問題,因爲它們不能被評估。 – 2012-04-17 19:33:37

回答

0

正如Endophage指出的那樣,玩sys.path確實很愚蠢。但是我想我已經開始了,因爲我不想執行任何Python代碼,這對於自動完成來說非常酷。我不認爲這是c_builtin模塊的大問題。但是,有些模塊確實需要正確的包路徑(請參閱有關段錯誤的更多內容)。

我甚至做了一個解決方法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.') 

這包括受涼SystemError,然後用它從sys.modules中。事實上,這非常愚蠢,因爲我不知道這些操作的任何副作用。當我測試PySide(這是另一個Qt包裝)時,段錯誤在某些情況下發生。

所以我想出了更加pythonic的解決方案來加載這樣的模塊:from PyQt4 import QtCorefrom numpy.random import random。有趣的是,用它們的全路徑加載這些模塊的內存佔用大約與sys.path差不多。

0

不知道爲什麼有人給你一個這個-1。在我對Python導入有自己的問題之後,我的信念是,當你混淆了sys.path時,你已經繞過了init .py文件,這些文件通常會被執行。 /usr/lib/pymodules/python2.7/numpy/usr/lib/pymodules/python2.7/numpy/random(可能)是python軟件包,並且包含init .py文件。只要導入了該包或子包中的任何內容,就會默認包含init文件。通過將路徑指向文件樹的更深層次,您已經繞過了這些init文件,改變了包的預期行爲。

也很好的信息從斯文。我認爲你的2個導入不在Python的相同運行實例內。如果他們是,那麼Sven的答案是相關的。

+0

搞亂sys路徑確實很愚蠢 - 通常。但是由於我正在寫一個自動完成,這實際上是一個不同的事情。我當然不想導入整個'numpy'庫。只是模塊,在其上執行一個'dir(mtrand)'(在exec內)。 – 2012-04-17 07:48:37

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'] 

這是不確定的行爲,所以任何事情都有可能發生。

+0

這可能是一個很好的提示,但我將它們導入到不同的python實例中。 - >所以這不是問題。 – 2012-04-17 07:41:41

+0

在不同的過程中嘗試它,效果將會是我所描述的(我猜上面的情況是你用未定義行爲描述的) – 2012-04-17 07:48:19