2

以下の問題のロジックに苦労しています。ロジックを釘付けにしたとしても、不器用に実装する可能性があることを知っているので、アドバイスは素晴らしいでしょう。

ファイルを表す辞書があります。

the_file = {'Filename':'x:\\myfile.doc','Modified':datetime(2012,2,3),'Size':32412}

フィルタのリストがあり、ファイル ディクショナリをフィルタして一致を判断したいと考えています。

filters = [
    {'Key':'Filename','Criteria':'Contains','Value':'my'},
    {'Key':'Filename','Criteria':'Does not end with','Value':'-M.txt'},
    {'Key':'Modified','Criteria':'After','Value':datetime(2012,1,1)}
    ]

これを行うための関数を作成する私の最善の試み(これは機能しません):

def is_asset(the_file, filters):
match = False
for f in filters:
    if f['Key'] == u'Filename':
        if f['Criteria'] == u'Contains':
            if f['Value'] in the_file['Filename']:
                match = True
        elif f['Criteria'] == u'Starts with':
            if the_file['Filename'].startswith(f['Value']):
                match = True
        elif f['Criteria'] == u'Ends with':
            if the_file['Filename'].endswith(f['Value']):
                match = True
        elif not f['Criteria'] == u'Does not end with':
            if the_file['Filename'].endswith(f['Value']):
                match = False
        elif f['Criteria'] == u'Equals':
            if os.path.basename(the_file['Filename']) == f['Value']:
                match = True
        elif f['Criteria'] == u'Does not contain':
            if f['Value'] in the_file['Filename']:
                match = False
    elif f['Key'] == u'Modified':
        mtime = int(os.path.getmtime(the_file['Filename']))
        if f['Criteria'] == u'Before':
            if f['Value'] > datetime.fromtimestamp(mtime):
                the_file['Modified'] = mtime
                match = True
        elif f['Criteria'] == u'After':
            if f['Value'] < datetime.fromtimestamp(mtime):
                the_file['Modified'] = mtime
                match = True
    elif f['Key'] == u'Size':
        size = long(os.path.getsize(the_file['Filename']))
        if f['Criteria'] == u'Bigger':
            if f['Value'] < size:
                the_file['Size'] = size
                match = True
            elif f['Value'] > size:
                the_file['Size'] = size
                match = True
    if match:
        return the_file
4

2 に答える 2

4

1つのメガファンクションでそれを実行しようとする代わりに、それをより小さなステップに分割します。

filenamecondmap = {
  u'Contains': operator.contains,
  u'Does not end with': lambda x, y: not x.endswith(y),
   ...
}

 ...

condmap = {
  u'Filename': filenamecondmap,
  u'Modified': modifiedcondmap,
   ...
}

次に、条件が得られるまで構造をウォークし、それを実行します。

condmap[u'Filename'][u'Contains'](thefile['Filename'], 'my')
于 2012-05-02T04:23:56.673 に答える
2

関数を「基準」として使用するだけです。これにより、大きなif-elseラダーを作成する必要がなくなるため、はるかに簡単になります。このようなもの:

def contains(value, sub):
    return sub in value

def after(value, dt):
    return value > dt

filters = [
    {'Key': 'FileName', 'Criteria': contains, 'Value': 'my'},
    {'Key': 'Modified', 'Criteria': after,  'Value': datetime(2012,1,1)}
]

for f in filters:
    if f['Criteria'](filename[f['Key']], f['Value']):
       return True
于 2012-05-02T04:34:35.510 に答える