2013-02-10 20 views
0

對於我目前的項目,我正在使用pyxb閱讀xml配置文件。但應該可以通過提供命令行參數來覆蓋一些設置(使用argparse進行分析)。
爲了獲得更多可讀代碼,我想使用通用方法並定義更新方法。參數更新必須使用try-catch-block,因爲pyxb在賦值時會驗證新的值(在這種情況下,檢查字符串是否符合模式)。如何更新循環中的pyxb樹狀對象?

這裏是我的嘗試:

def override_setup(exp, args): 
    for param, arg in [[exp.param1, args.param1], [exp.param2, args.param2]]: 
     if arg is None: 
      continue 

     # this doesn't work, because param just references the string object referenced by exp.param1? 
     try:     
      param = arg 
     except Exception as e: 
      print e 

    # the following works 
    exp.param1 = "stuff" 

我創建包含的pyxb參數映射到argparse命令行參數的清單。我認爲這是一切都開始出錯的地方。
我想用某種方式來使用某種循環來做這個更新(所以我不需要爲每個元素重複try-catch-block)。
不幸的是,exp似乎不是可迭代的。 exp的每個孩子都有一個成員_getDiagnosticName(),它返回一個字符串,我可以用它作爲映射到argparse讀取的參數。
我找到了article describing how to get a dict of the argparse results。所以映射(pyxb元素 - > argparse參數值)不再是問題。迭代是問題。

任何想法?

回答

0

搜索一些後,我終於找到了我一直在尋找解決方案:setattr()

def override_setup(exp, args): 
    opts = vars(args) 

    for param in ['param1', 'param2']: 
     if opts[param] is None: 
      continue 

     try: 
      setattr(exp, param, opts[param]) 
     except Exception as e: 
      print e 
0

我發現了一個可能的,但有點難看的解決方案。主要部分使用vars()(如文章我在問題中引用...在):

def override_setup(exp, args): 
    exp_dict = vars(exp) 
    opts = vars(args) 

    # iterate over node 
    for key in exp_dict: 
     cur_param = None 
     for param in ['param1', 'param2']: 
      # ugly workaround 
      # keys are like __{XML-Namespace-URI}_parent__param1 
      if key.endswith(param): 
       cur_param = param 

     if not cur_param or opts[cur_param] is None: 
      continue 

     try: 
      exp_dict[key] = opts[cur_param] 
     except Exception as e: 
      print e 

在我的情況exp_dict包含代表內部pyxb的東西,你不應該接觸至少6個元素。這是我不太喜歡這個解決方案的原因之一。但這是我現在最好的。