2017-04-06 46 views
3

所以,這是一個kluge。我正在與luigi和sciluigi合作。Lie isinstance

isinstance檢查是在sciluigi包,我寧願克魯格則有分支整個sciluigi這個小問題:)

簡單地說,我有子類封裝的一個類( luigi.LocalTarget) - 添加附加功能。該功能的偉大工程,但有在sciluigi包對象檢查...

sciluigi.dependencies.DependencyHelpers._parse_outputitem()

...這會導致因爲isinstance線被設置爲僅選中「TargetInfo」對象運行簡單地失敗。

我想要做的只是告訴我的孩子類「謊言」,以isinstance因此報告了一個TargetInfo對象,並將:d

寬恕要求提前:d

def _parse_outputitem(self, val, targets): 
    ''' 
    Recursively loop through lists of TargetInfos, or 
    callables returning TargetInfos, or lists of ... 
    (repeat recursively) ... and return all targets. 
    ''' 
    if callable(val): 
     val = val() 
    if isinstance(val, TargetInfo): 
     targets.append(val.target) 
    elif isinstance(val, list): 
     for valitem in val: 
      targets = self._parse_outputitem(valitem, targets) 
    elif isinstance(val, dict): 
     for _, valitem in iteritems(val): 
      targets = self._parse_outputitem(valitem, targets) 
    else: 
     raise Exception('Input item is neither callable, TargetInfo, nor list: %s' % val) 
    return targets 

錯誤消息:

2017-04-06 22:26:09,753 - PipeineTest1 - DEBUG - RunSubprocess:Traceback (most recent call last): 
2017-04-06 22:26:09,754 - PipeineTest1 - DEBUG - RunSubprocess: File "/Library/Python/2.7/site-packages/luigi/worker.py", line 305, in check_complete 
2017-04-06 22:26:09,754 - PipeineTest1 - DEBUG - RunSubprocess: is_complete = task.complete() 
2017-04-06 22:26:09,754 - PipeineTest1 - DEBUG - RunSubprocess: File "/Library/Python/2.7/site-packages/luigi/task.py", line 482, in complete 
2017-04-06 22:26:09,754 - PipeineTest1 - DEBUG - RunSubprocess: outputs = flatten(self.output()) 
2017-04-06 22:26:09,754 - PipeineTest1 - DEBUG - RunSubprocess: File "/Library/Python/2.7/site-packages/sciluigi/dependencies.py", line 99, in output 
2017-04-06 22:26:09,754 - PipeineTest1 - DEBUG - RunSubprocess: return self._output_targets() 
2017-04-06 22:26:09,755 - PipeineTest1 - DEBUG - RunSubprocess: File "/Library/Python/2.7/site-packages/sciluigi/dependencies.py", line 111, in _output_targets 
2017-04-06 22:26:09,755 - PipeineTest1 - DEBUG - RunSubprocess: output_targets = self._parse_outputitem(attrval, output_targets) 
2017-04-06 22:26:09,755 - PipeineTest1 - DEBUG - RunSubprocess: File "/Library/Python/2.7/site-packages/sciluigi/dependencies.py", line 132, in _parse_outputitem 
2017-04-06 22:26:09,755 - PipeineTest1 - DEBUG - RunSubprocess: raise Exception('Input item is neither callable, TargetInfo, nor list: %s' % val) 
2017-04-06 22:26:09,755 - PipeineTest1 - DEBUG - RunSubprocess:Exception: Input item is neither callable, TargetInfo, nor list: <Bioproximity.common.luigi_extensions.local_target.ToppasLocalTarget object at 0x110e48190> 

...不幸的是,這就是錯誤回溯該Sciluigi提供作爲輸出的100%。

sciluigi.dependencies.TargetInfo(對象)

class TargetInfo(object): 
    ''' 
    Class to be used for sending specification of which target, from which 
    task, to use, when stitching workflow tasks' outputs and inputs together. 
    ''' 
    task = None 
    path = None 
    target = None 

    def __init__(self, task, path, format=None, is_tmp=False): 
     self.task = task 
     self.path = path 
     self.target = luigi.LocalTarget(path, format, is_tmp) 

    def open(self, *args, **kwargs): 
     ''' 
     Forward open method, from luigi's target class 
     ''' 
     return self.target.open(*args, **kwargs) 

# ============================================================================== 
+2

難道你不能只用你自己的實現monkeypatch'_parse_outputitem'來省略那個步驟嗎? – karlson

+0

您沒有顯示任何實際存在問題的代碼。請儘量創建一個[MCVE](http://stackoverflow.com/help/mcve)並提供實際的錯誤細節,回溯等。 –

+0

@Karlson - 我可以monkeypatch,但是我們有一個自定義的sciluigi實現 - 它我試圖避免。 – RightmireM

回答

1

它看起來像你只需要繼承TargetInfo讓你的對象將通過isinstance檢查。你可以這樣說:

class Foo(<whatever other base classes you have>, TargetInfo): 
    ... 

如果你有TargetInfo作爲根後代那麼它不應該與類的功能造成干擾,因爲其他基類將覆蓋任何衝突的方法。

2

我想你需要創建一個TargetInfo子類,除了你已經有的LocalTarget子類。看起來你正在嘗試使用當前的子類作爲前者,當它是後者的一個實例時。傳遞您的自定義類的實例不起作用,因爲在同一地點傳遞常規LocalTarget也不起作用。

嘗試這樣:

class MyTargetInfo(TargetInfo):   # pick your own name 
    def __init__(self, task, path, *args): # you might want to explicitly name the args here 
     self.task = task 
     self.path = path 
     self.target = ToppasLocalTarget(*args) 

你要的類的實例傳遞給是給你的錯誤,當你給它你LocalTarget子類的實例功能。正如我評論的那樣,你應該給這個類一個更好的名字,也許給你需要明確傳遞給其他類的參數(而不是使用*args)命名(也可能給出默認值)。

如果在MyTargetInfo.__init__範圍內構建target不符合您的自定義班級的需求(例如,您需要提前創建它或重複使用同一個實例),您可以將已存在的LocalTarget傳遞給構造函數,並將其分配給self.target而不是創建新對象。我對你用來判斷這是不是一個好主意的圖書館知之甚少。

+0

非常完整的答案。完全正確。謝謝! – RightmireM