2012-09-07 192 views
0

我正在嘗試創建一個模塊來保存Fabric文件的配置。這個配置文件將保存項目相關的設置,所以我可以爲我們所有的項目使用相同的fabfile。Python模塊變量依賴關係

我想fabfile看起來像這樣:

import config 
from fabric.api import local 

def deploy(env='staging'): 
    config.env = env 
    local("xcopy {project_dir} {deploy_target} /u /r /y".format(project_dir=config.project_dir, 
                   deploy_target=config.deploy_target)) 
    #Ok, this will be more involved than that, but it is enough to explain my problem 

和配置文件看起來像這樣:

env = 'staging' 
project_dir = r'c:\some\unimportant\path' 
deploy_target = r'c:\some\target\path\based\on\{env}'.format(env=env) 

所以我可以使用: fab deployfab deploy:staging部署到分期環境和fab deploy:production部署到生產環境。

我想弄清楚當env變量發生變化時,如何更新模塊中的變量。

我希望我的配置文件儘可能簡單,理想情況下只是變量賦值,但如果真的需要,我可以使用一些函數。設置文件中會有很多變量,所以使用global關鍵字更新函數中的值看起來會非常難看。

+0

是否配置文件需要在部署時它被永久改變,或者是確定的,如果部署完成後,這些值將恢復爲默認值?後者應該很容易,但前者要複雜得多。 – Blckknght

+0

配置文件在每個項目的基礎上是唯一的。 config.py模塊中的設置基本上已經設置好了。他們不會經常改變。每個項目通常只有2-3個環境。路徑非常相似,只有幾個字符在改變,有時候是一個服務器名稱,但這是關於它的。 – Martin

+0

如果它們在部署後返回到它們的默認值,這是可以的,因爲fabfile中的所有命令都會採用一個env參數,它將在配置模塊中相應地設置值(如果我設法實現我想要做的)。 – Martin

回答

0

將配置參數存儲在字典中。

因此,在與__init__.py文件的目錄有一個文件名爲my_config.py(注意,這將會在你的python_path)的東西,如:

my_params = {'env': 'staging', 
      'project_dir': r'c:\some\unimportant\path', 
      'deploy_target': r'c:\some\target\path\based\on\staging', 
      } 

我不知道你怎麼打算將配置設置傳遞給fabfile,但是通過配置文件中的字典,訪問您的設置非常簡單。如果你把所有的配置設置在一個單一的字典(如上)定義的單個項目,然後下面就可以去參加你的fabfile:

config = __import__('my_config') 

在這一點上,你可以訪問您的配置設置:

env = config.my_params['env'] 

同樣,我不完全確定你打算如何傳遞你想要的配置,所以如果我錯過了該標記,請留下評論。無論如何,字典是像這樣存儲信息的pythonic方法,並且如果需要它們,可以很容易地導入這些值。

+0

目前,我有一個名爲Deploy的文件夾,其中包含fabfile.py和config.py。 該文件夾將被複制到我們擁有的每個項目中。 當我們創建一個新項目時,只需要更新config.py文件。 我想要做的是能夠在fabfile中調用'import config'。配置模塊導入後,我希望能夠通過調用'config.env ='environment_name''來設置環境。更改config.env的值應更新配置模塊中取決於此值的所有設置的值。 – Martin

+0

我不希望每個環境都有字典。 – Martin

+0

好的,我想我明白你在說什麼了。我會堅持認爲,使用字典是最簡單的方法來做你想要的。最重要的變化是您必須使用括號語法而不是點語法來訪問您的配置設置。如果你想走一條沒有字典的路線,你將會使用我認爲是黑客的東西。是否有一個特定的原因,你爲什麼不想使用字典? – Wilduck

0

我認爲您的config模塊中的變量在您更改config.env時得到更新,您將需要至少使用一個函數。

最簡單的方法可能是將env作爲變量,而改爲setEnv函數(將所有其他模塊變量設置爲適當的值)。另一個選擇是保留env,但要調用函數以獲取其他值(例如config.get_deploy_target())。

甚至可以使模塊看起來像只包含值,實際上其中的一些或全部是基於env或其他值計算的。這需要使用Python模塊查找系統做一些技巧,以便實際讀取來自類實例的值,而不是實際的模塊。這允許使用config模塊是簡單的代碼,但在製作config.py本身要複雜得多的成本:

# config.py 

class Config(object): 
    def __init__(self): 
     self.env = "staging" 
     self.project_dir = r'c:\some\unimportant\path' 

    @property 
    def deploy_target(self): 
     return r'c:\some\target\path\based\on\{env}'.format(env=self.env) 

import sys 
sys.modules["config"] = Config()