簡體   English   中英

交叉模塊變量

[英]cross module variable

這里,我對如何使用其他模塊的變量有了一個想法。 這一切都很好

import foo as bar

但是我不想將我的模塊導入為“ bar”,我想不帶任何前綴就使用它

from foo import *

使用此功能無法修改其他模塊中的變量。 閱讀會起作用! 任何想法? 建議?

簡短答案:不,這是不可能的,您必須使用前綴。

重要的是要了解, from foo import x, y x 復制到您的名稱空間。 等價於:

import foo
# COPY TO YOUR NAMESPACE
x = foo.x
y = foo.y
# `from foo import` does NOT leave `foo` in your namespace
def foo

這樣,每個模塊將獲得xy的本地副本。 更改x不會在其他模塊中看到,您也不會看到其他模塊所做的更改:-(

要更改變量的中央副本,必須導入模塊本身: import foo並更改foo.x 這樣,只有一個副本存在,每個人都在訪問它:-)

[鏈接的問題還提到了將共享變量放入內置模塊的可能性。 別! 這將消除閱讀時的前綴,但不會消除書寫的前綴,這是非常糟糕的樣式。]

保護Python的注意事項

如果您不滿意需要使用foo. 在這里加上前綴,您可能還會對self.的需求感到不滿self. 訪問對象變量的前綴。 最重要的是Python的工作方式-由於您沒有聲明變量,因此只能使用前綴。

但是還有一個好處:閱讀Python代碼時,您很容易看到每個變量的位置。 恕我直言,這非常好。

有力的證據:在其他語言(例如C ++ / Java)中,許多人m_所有對象變量名稱上的m_前綴等約定,以實現類似的效果...

風格備注

  1. 您不需要import foo as bar ,只需使用import foo
    as表單沒有做任何新的事情,它只是對其進行了重命名,這很令人困惑。
    僅當“ foo”是一個非常長的名稱時才有用; 一個特別可接受的情況是“ foo”存在於某些包中,因此您可以import long.package.foo as foo

  2. from foo import *在程序中被認為是非常糟糕的樣式,因為:

    • 讀取您的代碼的人不會知道名稱的來源。

    • 它會污染您的名稱空間,當來自不同模塊的名稱發生沖突時,可能導致細微的錯誤。

    from foo import x, y的顯式形式是可以的,但是如果您使用模塊中的許多名稱,則開始出現相同的問題。
    在這種情況下,最好import foo並顯式編寫foo.xfoo.y

底線:如有疑問,最好使用簡單的import foo

例外: 使用起來非常順手import *在交互式解釋實驗時。 但是請注意,它不能與reload()配合使用,因此在調試更改代碼時不要使用它。 (要調試正在編寫的模塊,最好在模塊的命名空間啟動一個新的解釋器-空閑狀態下的python -i mymodule.py / F5。)

據我所知,沒有辦法模塊中導入值並且無法通過導入范圍對其進行讀寫。 當您僅在Python中import foo時,它將創建一個名為foo的模塊對象。 在模塊對象上獲取和設置屬性將在模塊范圍內更改它們。 但是,當您from foo import something ,會導入foo並創建一個模塊對象,但不會返回。 取而代之的是,Python從foo復制您指定的值,並將其放在本地范圍內。 如果要導入的是intstr這樣的不可變類型,則無法更改它並使更改反映在foo模塊中。 與此類似:

>>> class N(object):
...   def __init__(self, value):
...     self.value = value
>>> n = N(3)
>>> value = n.value
>>> print value, n.value
3 3
>>> value = 4
>>> print value, n.value
4 3

除了簡單的技巧外,如果您確實希望能夠修改模塊的變量,則需要導入模塊本身並在模塊上修改變量。 但是通常,必須這樣做表明設計不良。 如果您是有問題的foo模塊的編寫者,則可能需要查看其他一些更Python的方法來解決問題。

通過import foo from bar使用import foo from bar您不會將bar作為變量導入,而是作為常量導入。

from foo import *被皺眉了(不幸的是,對我來說,由Google的樣式指南 ,由OLPC樣式指南所支持 -您應該看到它,因為它對為什么這樣做不好有最好的解釋-但不幸的是, PEP-8沒有。) -它導致不可讀的代碼。

考慮:

from foo import *
from bar import *
from baz import *

dostuff()

如果您在運行dostuff()出錯,那么在哪里尋找問題? 它可能來自任何這些進口。

對於可讀,可維護的代碼,請堅持使用from foo import bar 對於可讀的,模塊化的,可維護的代碼,請不要使用全局變量-擴展bar (如果不能更改上游源代碼,則通過子類化)可以公開用於修改需要訪問的值的方法。

暫無
暫無

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

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