国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

Python相對導入導致SystemError的解決方案(譯)

ethernet / 1523人閱讀

摘要:相對導入相對導入使用模塊的決定它是否在一個包內。當你是用類似進行相對導入的時候,點表明在包的層次中上升多少。所以,你不能在交互式會話中直接使用任何相對導入。

源題目與答案地址如下http://stackoverflow.com/questions/14132...。下面是我的翻譯(看作機翻也行),以及原文。

這個問題是如何解決在相對導入的時候,如果出現"System Error"的時候的解決方案。順帶一提,這個問題好像出在源碼上,在issue 18018得到解決,附上這個據說可以解決問題的地址:解決方案。我不知道怎么使用,希望知道的讀者(如果有的話)可以告訴我~

腳本VS模塊

這里是解釋。長話短說,這是因為在運行一個Python文件和從什么地方導入那個文件之間,存在一個巨大的差異。你只要明白:一個文件到底在哪里并不能決定Python覺得它在哪個包里面。此外,這實際上取決于你是如何將這個文件導入到Python中的。

導入一個Python文件有兩種方法:作為頂層文件,或者作為一個模塊。如果你直接運行它,這個文件就會被當作頂層文件來執行,比如在命令行中輸入python myfile.py。如果你使用python -m myfile,或者它是通過其他文件的import語句導入的,那這個文件就會作為一個模塊被導入。一次只能有一個頂層文件;頂層文件是你一開始運行的Python文件。

名字

當一個文件被導入的時候,它會得到一個名字(存儲在其__name__屬性中)。如果它是作為頂層文件被導入的,那么它的__name__就是__main__;如果它是作為一個模塊被導入的,則它的__name__就是它的文件名,先于任何它所組成的包或子包,由點號分開。

所以,看看你這里的例子

package/
__init__.py
subpackage1/
    __init__.py
    moduleX.py
moduleA.py
enter code here

如果你導入moduleX(注意,導入而非運行),那么它的名字就是package.subpackage1.moduleX。如果你導入moduleA,則它的名字就是package.moduleA??墒?,如果你直接從命令行運行moduleX,則它的名字就會被__main__取而代之,moduleA也是如此。當一個模塊作為頂層文件被運行的時候,其會失去本身的名字,并由__main__取而代之。

不通過包含它的包來獲取一個模塊

這里有一個附送的小技巧:模塊名取決于它是從所在的目錄直接導入,或者通過一個包導入的。這只有在你從目錄中運行Python,以及嘗試在相同的目錄(或者它的子目錄)導入一個文件的時候有差別。舉個例子,如果你在目錄package/subpackage1運行Python解釋器,然后導入moduleX,moduleX的名字就只會是moduleX,而不是package.subpackage1.moduleX。這是因為,Python將當前的路徑添加到模塊搜索路徑的開頭;如果它發現當前目錄有一個需要運行的模塊,它不會明白這個目錄是包的一部分,而這個包的信息也不會成為模塊名的一部分。

如果你只是交互式地運行解釋器,會出現一個特殊情況(比如:輸入python并進入shell)。這種情況下,這個交互式會話的名字是__main__

你的錯誤實際上是:如果一個模塊名沒有點,它不會被視作包的一部分。這個文件實際上在哪個目錄無關緊要。唯一相關的是,它的名字是什么,而它的名字取決于你是如何導入它的。

現在,看看你在問題中所引用的內容:

相對導入使用一個模塊的__name__屬性來決定模塊在包中的層次。如果模塊的名字不包含任何模塊信息(比如被設置為__main__),那么相對導入將會把該模塊視作頂層模塊,忽視其在文件系統中的實際位置。

相對導入……

相對導入使用模塊的__name__決定它是否在一個包內。當你是用類似form .. import foo進行相對導入的時候,點表明在包的層次中上升多少。舉個例子,如果你當前的模塊的名字是package.subpackage1.moduleX,那么..moduleA就表示模塊package.moduleA。要想讓from .. import語句起作用,模塊的名字至少有在import語句中的點的數量。

... 只是在包中是相對的

可還是,如果你的模塊名是__main__,那么它不會被當作一個包。它的名字里面沒有點,因此你不能在文件內使用from .. import 語句。如果你嘗試這么干,你會獲得錯誤relative-import in non-package。

腳本不可以相對地導入

你想做的事情大概是嘗試要從命令行中運行moduleX。當你這么干的時候,它的名字會被設置為__main__,這意味著里面的相對導入失效了,因為:它的名字并沒有顯示出它在一個包里面。注意,這會發生在你從相同的目錄運行中運行Python并試圖導入那個模塊的時候,這是因為:如上所說,python會在意識到這是包的一部分之前,在當前目錄下“過早”找到那個模塊。

你也要記得,當你運行一個交互式解釋器的時候,交互式會話的name總是__main__。所以,你不能在交互式會話中直接使用任何相對導入。相對導入只能使用在模塊文件內。

兩個解決方案:

如果你真的向直接運行moduleX,但你希望它可以被視作包的一部分,那使用python -m package.subpackage.moduleX運行即可。選項-m告訴Python將其作為一個模塊而非頂層文件導入。

如果你不不希望真的運行moduleX,你只想運行其他使用了在moduleX里的函數的腳本,如myfile.py。在這種嗯情況下,將myfile.py放到其他地方——不在包目錄里面——并運行它。如果在myfile.py里面,你做點類似從package.moduleA里面導入spam,它會做的很好~

注意事項:

對于這兩個解決方法的任意一個來說,包目錄必須在模塊搜索路徑sys.path中。如果不是的話,你不能確實可靠地使用包里面的任何東西。
自從Python2.6以來,包依賴的解決不僅僅取決于模塊的名字,還有模塊的__package屬性。這使我為什么避免使用__name__來指代模塊的名字。一個模塊的名字現在可能是__package__ + __name__了,除非沒有包。

原文如下:
Script vs. Module

Here"s an explanation. The short version is that there is a big difference between directly running a Python file, and importing that file from somewhere else. Just knowing what directory a file is in does not determine what package Python thinks it is in. That depends, additionally, on how you load the file into Python (by running or by importing).

There are two ways to load a Python file: as the top-level script, or as a module. A file is loaded as the top-level script if you execute it directly, for instance by typing python myfile.py on the command line. It is loaded as a module if you do python -m myfile, or if it is loaded when an import statement is encounted inside some other file. There can only be one top-level script at a time; the top-level script is the Python file you ran to start things off.

Naming

When a file is loaded, it is given a name (which is stored in its name attribute). If it was loaded as the top-level script, its name is __main__. If it was loaded as a module, its name is the filename, preceded by the names of any packages/subpackages of which it is a part, separated by dots.

So for instance in your example:

package/

__init__.py
subpackage1/
    __init__.py
    moduleX.py
moduleA.py

enter code here

if you imported moduleX (note: imported, not directly executed), its name would be package.subpackage1.moduleX. If you imported moduleA, its name would be package.moduleA. However, if you directly run moduleX from the command line, its name will instead be __main__, and if you directly run moduleA from the command line, its name will be __main__. When a module is run as the top-level script, it loses its normal name and its name is instead __main__.

Accessing a module NOT through its containing package

There is an additional wrinkle: the module"s name depends on whether it was imported "directly" from the directory it is in, or imported via a package. This only makes a difference if you run Python in a directory, and try to import a file in that same directory (or a subdirectory of it). For instance, if you start the Python interpreter in the directory package/subpackage1 and then do import moduleX, the name of moduleX will just be moduleX, and not package.subpackage1.moduleX. This is because Python adds the current directory to its search path on startup; if it finds the to-be-imported module in the current directory, it will not know that that directory is part of a package, and the package information will not become part of the module"s name.

A special case is if you run the interpreter interactively (e.g., just type python and start entering Python code on the fly). In this case the name of that interactive session is __main__.

Now here is the crucial thing for your error message: if a module"s name has no dots, it is not considered to be part of a package. It doesn"t matter where the file actually is on disk. All that matters is what its name is, and its name depends on how you loaded it.

Now look at the quote you included in your question:

Relative imports use a module"s name attribute to determine that module"s position in the package hierarchy. If the module"s name does not contain any package information (e.g. it is set to "main") then relative imports are resolved as if the module were a top level module, regardless of where the module is actually located on the file system.

Relative imports...

Relative imports use the module"s name to determine where it is in a package. When you use a relative import like from .. import foo, the dots indicate to step up some number of levels in the package hierarchy. For instance, if your current module"s name is package.subpackage1.moduleX, then ..moduleA would mean package.moduleA. For a from .. import to work, the module"s name must have at least as many dots as there are in the import statement.

... are only relative in a package

However, if your module"s name is __main__, it is not considered to be in a package. Its name has no dots, and therefore you cannot use from .. import statements inside it. If you try to do so, you will get the "relative-import in non-package" error.

Scripts can"t import relative

What you probably did is you tried to run moduleX or the like from the command line. When you did this, its name was set to __main__, which means that relative imports within it will fail, because its name does not reveal that it is in a package. Note that this will also happen if you run Python from the same directory where a module is, and then try to import that module, because, as described above, Python will find the module in the current directory "too early" without realizing it is part of a package.

Also remember that when you run the interactive interpreter, the "name" of that interactive session is always __main__. Thus you cannot do relative imports directly from an interactive session. Relative imports are only for use within module files.

Two solutions:

If you really do want to run moduleX directly, but you still want it to be considered part of a package, you can do python -m package.subpackage.moduleX. The -m tells Python to load it a s a module, not as the top-level script.

Or perhaps you don"t actually want to run moduleX, you just want to run some other script, say myfile.py, that uses functions inside moduleX. If that is the case, put myfile.py somewhere else --- not inside the package directory -- and run it. If inside myfile.py you do things like from package.moduleA import spam, it will work fine.

Notes

For either of these solutions, the package directory (package in your example) must be accessible from the Python module search path (sys.path). If it is not, you will not be able to use anything in the package reliably at all.

since Python 2.6, the module"s "name" for package-resolution purposes is determined not just by its __name__ attributes but also by the __package__ attribute. That"s why I"m avoiding using the explicit symbol __name__ to refer to the module"s "name". Since Python 2.6 a module"s "name" is effectively __package__ + "." + __name__, or just __name__ if __package__ is None.)

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/37851.html

相關文章

  • python相對導入

    摘要:包中的一個模塊可以采用相對路徑導入包,不影響模塊功能一個腳本未成為模塊,即其目錄及父目錄內無可以采用相對路徑導入包,并以腳本模式運行。參考相對導入與絕對導入 絕對路徑導入格式為import a.b或者from a import b,相對路徑導入格式為from . import b或者from ..a import b。 python2默認為相對路徑導入,python3默認為絕對路徑導...

    crossoverJie 評論0 收藏0
  • python基礎教程:模塊高級技巧

    摘要:標準模塊附帶了一個標準模塊庫。它返回一個如果調用不傳遞參數,則列出當前已經定義的所有名字用可以查看所有的內置類型變量函數等,方法是借助標準模塊模塊高級技巧總結的搜索路徑,順序一定要搞得清編譯后的文件內置函數查看模塊定義的名字。 上一節,我們講解了Python模塊的基礎知識,這一節我們繼續深入了解模塊的更多知識,從而讓大家全面了解、掌握和運用模塊到我們實際的編程中。 在上一節中有一句話接...

    JasinYip 評論0 收藏0
  • []JavaScript ES6模塊指南

    摘要:模塊可以導入和導出各種類型的變量,如函數,對象,字符串,數字,布爾值,等等。所以這可能會導致一些不符合預期的行為??勺兊幕绢愋椭翟趯胍恍┗绢愋偷闹等鐢底?,布爾值或字符串時,可能會產生一個有趣的副作用。 前言 ECMAScript 2015(又稱ES6)提供了一個前端JavaScript缺失已久的特性 —— 模塊。ES2015中的模塊參考了CommonJS規范(目前Node.js的...

    yimo 評論0 收藏0
  • 】JavaScript 命名空間

    摘要:前綴命名空間如果命名空間的目的是避免沖突的話。語言程序經常使用前綴命名空間。我認為前綴命名空間是中最清楚明白的命名空間系統。對象命名空間的一個問題是它會導致與面向對象消息傳遞混淆。嵌套命名空間的幻覺在中也存在。 原文鏈接:《JavaScript Namespacing》譯文原鏈:【譯】JavaScript 命名空間 JavaScript 中有很多可以給你的對象安全分配命名空間的方法。這...

    liujs 評論0 收藏0
  • []OpenCV Text Detection (EAST text detector)

    摘要:的文本檢測器是一種基于新穎架構和訓練模式的深度學習模型。深度學習文本檢測器圖文本檢測全卷積網絡的結構等人的圖。隨著和的發布,我們現在可以使用一種名為的基于深度學習的文本檢測器,它基于等人的年論文一種高效精確的場景文本檢測器。 by Adrian Rosebrock on August 20, 2018 in Deep Learning, Optical Character Recogn...

    VincentFF 評論0 收藏0

發表評論

0條評論

最新活動
閱讀需要支付1元查看
<