1

我有一系列函数应用于数据集中的每条记录,以生成存储在字典中的新字段(记录——“文档”——使用 MongoDB 存储)。我将它们全部分解,因为它们基本上是不相关的,然后通过将它们作为列表传递给一个函数,该函数迭代每个记录的每个操作并添加结果,从而将它们重新绑定在一起。

令我恼火的是我是如何以一种看起来相当不雅的方式来处理它的。半重复的名字等等。

def _midline_length(blob):
    '''Generate a midline sequence for *blob*'''
    return 42
midline_length = {
        'func':  _midline_length,
        'key': 'calc_seq_midlen'} #: Midline sequence key/function pair.

很多这些...

do_calcs = [midline_length, ] # all the functions ...

然后像这样调用:

for record in mongo_collection.find():
    for calc in do_calcs:
        record[calc['key']] = calc['func'](record) # add new data to record
    # update record in DB

像这样拆分键可以更轻松地删除数据库中的所有计算字段(在设置完所有内容后毫无意义,但在开发代码和方法时它很方便)。

我曾想过可能使用类,但它似乎更像是一个ab使用:

class midline_length(object):
    key = 'calc_seq_midlen'
    @staticmethod
    def __call__(blob):
        return 42

然后我可以创建一个实例列表 ( do_calcs = [midline_length(), ...]) 并通过调用每个事物或拉出它的key成员来运行。或者,似乎我可以任意将成员添加到函数中,def myfunc():然后myfunc.key = 'mykey'……这似乎更糟。更好的想法?

4

2 回答 2

3

您可能希望为此目的使用装饰器。

import collections
RecordFunc = collections.namedtuple('RecordFunc', 'key func')

def record(key):
    def wrapped(func):
        return RecordFunc(key, func)
    return wrapped

@record('midline_length')
def midline_length(blob):
    return 42

现在,midline_length实际上不是一个函数,而是一个RecordFunc对象。

>>> midline_length
RecordFunc(key='midline_length', func=<function midline_length at 0x24b92f8>)

它有一个func属性,即原始功能,还有一个key属性。

如果它们被添加到同一个字典中,您可以在装饰器中执行此操作:

RECORD_PARSERS = {}

def record(key):
    def wrapped(func):
        RECORD_PARSERS[key] = func
        return func
    return wrapped

@record('midline_length')
def midline_length(blob):
    return 42
于 2013-05-15T00:21:48.953 回答
0

这对装饰师来说是一份完美的工作。就像是:

_CALC_FUNCTIONS = {}
def calcfunc(orig_func):
    global _CALC_FUNCTIONS
    # format the db name from the function name.
    key = 'calc_%s' % orig_func.__name__
    # note we're using a set so these will
    _CALC_FUNCTIONS[key] = orig_func
    return orig_func

@calcfunc
def _midline_length(blob):
    return 42

print _CALC_FUNCTIONS
# prints {'calc__midline_length': <function _midline_length at 0x035F7BF0>}

# then your document update is as follows
for record in mongo_collection.find():
    for key, func in _CALC_FUNCTIONS.iteritems():
        record[key] = func(record)
    # update in db

请注意,您也可以像 Dietrich 指出的那样将属性存储在函数对象本身上,但您可能仍需要保留一个全局结构来保留函数列表。

于 2013-05-15T00:42:34.107 回答