2011-08-12 100 views
2

我是python的新手,並且被某些行爲困惑。python封裝範圍困惑

我有一個名爲d的目錄。在此目錄中,我有兩個文件:

__init__.py

from d import * 

d.py

var = None 

def printVar(): 
    global var 
    print "from d: var=%s" % `var` 

從上面d的目錄,我得到蟒蛇內這種互動:

>>> import d 
>>> d.var = 5 
>>> d.printVar() 
from d: var=None 

爲什麼var沒有從d.py的角度改變?

我真正的目標是要做到以下幾點:

  • 保持__init__.py
  • 能夠改變d.py -global變量

如果它的確與衆不同,我有多個文件在我的軟件包目錄中,將它們組合成單個文件是次優的。

什麼是可接受的方式來做到這一點?

+0

關於Python的最佳實踐,請注意一點......如果可以,請避免使用「*」導入。有不止一個是模塊會導致問題。不要在'__init __。py'文件中放入任何東西。只需使用'from d import X'風格。不要在模塊外改變模塊中的全局變量。使用一個類來包含這樣的狀態。 – Keith

回答

2

當你說:

import d 

你正在導入軟件包,而不是模塊。

只需導入模塊d內包:

>>> from d import d 
>>> d.var = 5 
>>> d.printVar() 
from d: var=5 
+1

澄清:在原代碼中,'d.var = 5'將'd' **包**的'var'屬性重新綁定爲5(它已經被'from d import *綁定到'None' '__init __。py'中),但是保持''d' **模塊**的'var'屬性不變。調用'd.printVar()'從包中訪問'printVar',這發生在使用模塊'var'屬性的模塊中找到的函數。如果'var'已經初始化爲'[]',而我們做了'd.var.append('foo')',那麼它就會「工作」,因爲我們會改變一個可變值而不是重新綁定變量。 –

+0

謝謝!我想我會給d.py添加一個setVar()函數來處理這個問題。 – Tyler

+0

@Karl:很好的解釋。 – Gerrat

0

我認爲全球var的實際名稱應該是d.d.var(因爲它是在模塊d封裝d

,所以你可以

1)只要把它稱爲d.d.var當你設置

2)請在d.py

不幸的是,這些制定者可能不會工作:

一)將其複製到d.var和嘗試,並設置有(你有你的問題) - 這是一個不同的變量

一)導入回像from __init__ import var(遞歸進口)

0
from X import * 

將所有來自X的名字到本地模塊。因此,修改本地模塊將不會修改原始內容。

至於你真正想做什麼,你可以使用一些python hackery,並用你自己的模塊對象替換,這會重載指定屬性的操作。但不要這樣做。這將需要很多代碼,讓你看起來很奇怪。

我建議有一個foo的客戶端代碼可以調用的函數。