2017-04-24 116 views
1

With Python doit我想通过从文件(在早期任务中生成的)中读取文件列表来生成子任务,然后为每个文件生成yield文件:Python doit:使用从以前的任务生成的文件创建子任务

def task_generates_list_of_files(): 

    def generate_file(): 

     with open('list_of_files.txt', 'w') as fo: 

      for x in range(20): 
       fo.write(f'thing_{x}.txt\n') 

    return { 
     'actions': [generate_file], 
     'targets': ['list_of_files.txt'] 
    } 

def task_generate_subtasks_using_file(): 

    with open('list_of_files.txt', 'r') as fo: 

     for filename in fo: 

      filename = filename.strip() 

      yield { 
       'name': filename, 
       'actions': [f'program_to_run {filename}'], 
       'file_dep': ['list_of_files.txt'] 
      } 

但是,由于list_of_files.txt时正在建立的任务由DOIT不存在,它提出了一个FileNotFoundError例外。

我见过this answer,但我并不清楚,getargs可以生成子任务时的工作,因为我没有将能够通过文件列表循环,直到它们被注入到Python的行动,在这一点上,我不能产生任何子任务。这样做的结果是:

Python Task error:... 
It must return: 
False for failed task. 
True, None, string or dict for successful task 
returned <generator object... 
+0

的'返回<发电机对象...'是一个重大线索。 'task_generate_subtasks_using_file()'就是所谓的[generator function](https://docs.python.org/3/glossary.html#term-generator),因为它包含一个'yield'语句。第一次被调用时,它返回一个可迭代的生成器对象,并且**它的**方法,比如'next()'必须被用来检索生成的值。有关详细信息,请参阅标题为[** Yield expressions **]的文档部分(https://docs.python.org/3/reference/expressions.html#yieldexpr)。 – martineau

+0

我明白,但问题是特定于Python'doit'(http://pydoit.org/index.html),您可以在其中使任务函数返回字典,其中包含要运行的doit任务的字典,或者使用'yield'来做“子任务”。但是我无法在'doit'运行脚本时运行的任务定义中打开我的'list_of_files.txt',因为它在第一个任务运行之前不存在。第二部分解释了我不能使用一种方法在'doit'任务之间传递值(称为'getargs'),因为我无法从任务中的函数中产生子任务(http://pydoit.org /dependencies.html#getargs) – Harry

+0

请参阅[如何创建一个** Minimal **,Complete和Verifiable example_](https://stackoverflow.com/help/mcve)来重现问题,然后有人可能能够告诉你如何使用'getargs'来完成你想要做的事情。 – martineau

回答

1

最后,我已经错过这是我从来没有DOIT文档中看到过:delayed tasks。您可以使用create_after推迟创建任务,直到执行给定任务。

在我而言,这允许list_of_files.txttask_generates_list_of_files生成之前list_of_files.txt被读取的task_generate_subtasks_using_file任务定义中:

from doit import create_after 

# Show output 
DOIT_CONFIG = { 
    'verbosity': 2 
} 

def task_generates_list_of_files(): 

    def generate_file(): 

     with open('list_of_files.txt', 'w') as fo: 

      for x in range(20): 
       fo.write(f'thing_{x}.txt\n') 

    return { 
     'actions': [generate_file], 
     'targets': ['list_of_files.txt'] 
    } 

@create_after('generates_list_of_files') 
def task_generate_subtasks_using_file(): 

    with open('list_of_files.txt', 'r') as fo: 

     for filename in fo: 

      filename = filename.strip() 

      yield { 
       'name': filename, 
       'actions': [f'echo {filename}'], 
       'file_dep': ['list_of_files.txt'] 
      }