簡體   English   中英

Python * 進口

[英]Python * imports

我通常被告知以下是不好的做法。

from module import *

主要原因(或者我被告知)是您可能會導入您不想要的東西,並且它可能會影響另一個模塊中類似名稱的 function 或 class 。

但是,PyQt 呢?

from PyQt4.QtCore import *

我見過的每個示例都是這樣編寫的,主要是因為從 Qt 導出的所有內容都以“Q”開頭,因此不會影響任何內容。

共識是什么? 使用 * 進口總是不好的嗎?

編輯:

為了清楚起見,這個問題專門針對使用 PyQt4。 這與我設計其他項目的方式無關。

基本上,我發現 PEP8 編碼提高了我的代碼可讀性,除了導入 PyQt4 方面,所以直到現在我都沒有理會純粹主義者的皺眉。 但是現在我的開發組正在決定一個約定,我想知道這是否是“實用性勝過純度”的場景,或者我是否應該接受它並處理可怕的 PyQt4 導入

from PyQt4.QtGui import QComboBox, QLineEdit, QLayout, Q;lakdfaf.......

這可能會演變成一場宗教戰爭。 這是您是否想明確或是否想避免過於冗長的問題。 一般來說,遵循Python 的 Zen ,最好是明確的,但有時人們只是覺得列出來自特定模塊的每個導入並不實用。

我的一般規則是,如果我不編寫模塊,我不會全部導入。 我最大的恐懼實際上是編寫可能已在導入模塊中定義的局部變量。 因此,為了避免輸入長模塊名稱,我使用 import as 功能。 以您的模塊為例,我將執行以下操作:

import PyQt4.QtCore as qt

話雖如此,我編寫了許多支持模塊,我將導入所有內容。 就像 pyqt 模塊一樣,我用一個描述性的名稱來命名它們,這有助於顯示它來自哪個模塊。

按評論編輯
當我使用 import* 時,我的支持模塊不包含類或任何可以創建新實例的東西。 它們往往是僅修改現有實例的函數組。 為了幫助澄清我的觀點:如果我是源代碼的所有者並且我將是主要維護者,我將使用 import* 否則我將使用 import as。

我使用 import as 功能的另一個原因是允許我模擬模塊以進行調試。 在我現在正在進行的一個項目中,我使用 pyVisa 與許多 GPIB 設備進行通信。 當我沒有連接到設備 GPIB 網絡時,我可以使用 dummy_visa 模塊寫入標准輸出(以驗證我發送的格式正確)並返回一個隨機數(以測試我的應用程序)。 見下文

if visa_debug:
    import dummy_visa as visa
else:
    import visa
gpib = visa.Instrument("GPIB0::10")
gpib.write("MEAS:VOLT?")

對已經在命名約定中包含命名空間的模塊(例如 PyQT 的Q* )進行顯式例外是完全合理的。 但是,我建議明確默認仍然是“不要使用它”,並在您的編碼指南中簡單地列出這個例外。

import * is also acceptable when it is used as a namespace manipulation trick within an application (the two forms of that I am familiar with are optional C acceleration modules that are imported at the end of the pure Python version, and "flattening" a package __init__中的命名空間)。 關鍵是導入模塊和被導入模塊都在同一組開發人員的控制之下,因此避免命名空間沖突完全在他們的控制范圍內。

最后一個例外是為了方便交互式提示。

在其他情況下,最好要么導入特定名稱,要么通過模塊名稱間接引用它們(或者,如果有一些常用的引用項,則同時執行以下操作:

import module # Can access any from module import a, b, c # 但是我們引用了很多,所以直接檢索

教程,第 6 章

請注意,通常不贊成從模塊或 package 導入 * 的做法,因為它通常會導致代碼可讀性差。 但是,可以使用它來節省交互式會話中的輸入。

教程,第 10 章

請務必使用 import os 樣式而不是 from os import *。 這將使 os.open() 不會遮蔽內置的 open() function,后者的操作方式大不相同。

因此,有時這似乎絕對是個壞主意; 大多數時候不是最好的主意; 並且在您想要減少輸入的情況下(例如在交互式會話中)是一個可接受的快捷方式。

我發現import *被濫用了,並且可能成為維護方面的難題,所以我避免使用它,因為這個原因以及 state 的其他原因。 也就是說,我覺得簡短的交互式會話沒問題,例如from pylab import *

在生產代碼中,對於像PyQt4.QtCore這樣您計划使用許多符號的包,我將使用以下語法之一來明確符號來自哪個命名空間:

from PyQt4 import QtCore
# explicit where the symbol came from
QtCore.QTime()

import PyQt4.QtCore as QT
# less desirable since you need to look in the header to find out what QT is
# but I still prefer it to import *
QT.QTime()

一般來說,如果您要使用from X import Y ,最好明確說明您要導入的內容。 這不僅是因為它更安全,還因為它使您的代碼更具可讀性(並且升級到您正在使用的第三方模塊不會有太多可能意外破壞您的代碼)。

在一些演示大包的代碼示例中,例如 Qt 或 matplotlib,這些示例將使用from module import *因為它們通常只從一個模塊導入,這樣可以節省鍵入並讓示例代碼切入主題。 你沒有理由不能在你的代碼中這樣做,但至少要適度使用它,特別是如果它位於大型源文件中或其他人會查看你的代碼時。

PyQt 設計是橋下的水。 我不確定這是不是最好的東西,但它可能受到 Qt 設計方式的影響。 AFAIK,Qt 歷史上沒有使用 C++ 命名空間(我不確定它現在是否使用它們),因此必須使用前綴。 但所有這些設計決策可能都發生在 10 多年前,現在應該不會影響您的設計決策。

我知道,如果我現在正在設計一個庫,我肯定會選擇使用 package 命名空間(您可以在 Python 中顯式導入)而不是前綴。 假設我的前綴是 Pfx - 如果庫用戶不關心每次需要 function 時都寫PfxFunc() ,他當然不會關心Pfx.Func()中的額外字符,尤其是當他可以使用 import 時特定的符號名稱以進一步縮短它。

考慮這種情況

from foo import *
from bar import *

x=baz()

現在假設foo有一個名為baz()的 function,我們在代碼中使用它並且一切正常。 幾個月或幾年過去了, bar的作者添加了一個名為baz()的 function 。 有人更新了 egg ang bingo - 我們在程序中存在潛在的難以檢測的錯誤。

更何況光看那三行代碼,不去看看foobar就分不清baz是從哪里來的

我唯一一次使用import *是在解釋器中保存一些輸入

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM