骗人
Lie to isinstance
所以,这是一个问题。我正在与 luigi 和 sciluigi 合作。
isinstance
检查在 sciluigi 包中,我宁愿 kluge 它然后不得不为这个小问题分支整个 sciluigi :)
简而言之,我必须子class 包的 class 之一 (luigi.LocalTarget)- 以添加额外的功能。该功能运行良好,但在 sciluigi 包中有一个 object 检查...
sciluigi.dependencies.DependencyHelpers._parse_outputitem()
...导致 运行 失败只是因为 isinstance
行设置为仅检查 'TargetInfo' objects。
我想做的就是告诉我的 child class 到 'lie' 到 isinstance
所以它报告为 TargetInfo
object 并通过 :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(object)
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)
# ==============================================================================
看来您只需要 subclass TargetInfo
这样您的对象就会通过 isinstance
检查。你可以这样:
class Foo(<whatever other base classes you have>, TargetInfo):
...
如果您将 TargetInfo
作为根后代,那么它不应干扰 class 的功能,因为其他基础 classes 将覆盖任何冲突的方法。
我认为除了您已有的 LocalTarget
subclass 之外,您还需要创建一个 TargetInfo
subclass。看起来您目前正在尝试将当前的 subclass 用作前者,而它是后者的一个实例。传递自定义 class 的实例不起作用,因为在同一位置传递常规 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)
您需要将 this class 的实例传递给在给它一个 [=12= 的实例时给您错误的函数] 子class。正如我评论的那样,你应该给 class 一个更好的名字,也许给你需要明确传递给你的其他 class 的参数命名(并且可能给出默认值)(而不是使用 *args
).
如果在 MyTargetInfo.__init__
中构建 target
不能很好地满足您自定义 class 的需求(例如,您需要提前创建它或重复使用相同的实例几次),你可以将一个已经存在的 LocalTarget
传递给构造函数,然后将它分配给 self.target
而不是创建一个新对象。我对您使用的库了解不多,无法判断这是否是个好主意。
所以,这是一个问题。我正在与 luigi 和 sciluigi 合作。
isinstance
检查在 sciluigi 包中,我宁愿 kluge 它然后不得不为这个小问题分支整个 sciluigi :)
简而言之,我必须子class 包的 class 之一 (luigi.LocalTarget)- 以添加额外的功能。该功能运行良好,但在 sciluigi 包中有一个 object 检查...
sciluigi.dependencies.DependencyHelpers._parse_outputitem()
...导致 运行 失败只是因为 isinstance
行设置为仅检查 'TargetInfo' objects。
我想做的就是告诉我的 child class 到 'lie' 到 isinstance
所以它报告为 TargetInfo
object 并通过 :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(object)
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)
# ==============================================================================
看来您只需要 subclass TargetInfo
这样您的对象就会通过 isinstance
检查。你可以这样:
class Foo(<whatever other base classes you have>, TargetInfo):
...
如果您将 TargetInfo
作为根后代,那么它不应干扰 class 的功能,因为其他基础 classes 将覆盖任何冲突的方法。
我认为除了您已有的 LocalTarget
subclass 之外,您还需要创建一个 TargetInfo
subclass。看起来您目前正在尝试将当前的 subclass 用作前者,而它是后者的一个实例。传递自定义 class 的实例不起作用,因为在同一位置传递常规 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)
您需要将 this class 的实例传递给在给它一个 [=12= 的实例时给您错误的函数] 子class。正如我评论的那样,你应该给 class 一个更好的名字,也许给你需要明确传递给你的其他 class 的参数命名(并且可能给出默认值)(而不是使用 *args
).
如果在 MyTargetInfo.__init__
中构建 target
不能很好地满足您自定义 class 的需求(例如,您需要提前创建它或重复使用相同的实例几次),你可以将一个已经存在的 LocalTarget
传递给构造函数,然后将它分配给 self.target
而不是创建一个新对象。我对您使用的库了解不多,无法判断这是否是个好主意。