def METHOD_NAME(self, is_udaf=None, expect_dtype=None):
    '''
    挑选一个函数
    :param is_udaf: 是否是udaf
    :param expect_dtype: 期望的函数返回类型
    :return: UDFDesc
    '''
    # 创建一个函数 用来判断返回类型是否符合预期
    filter_func = lambda x: expect_dtype is None or x.return_type == expect_dtype
    if is_udaf:
        cands = self.filter_functions(self.udafs, filter_func)
    elif is_udaf is None:
        cands = self.filter_functions(self.udafs, filter_func) + \
                self.filter_functions(self.udfs, filter_func)
    else:
        cands = self.filter_functions(self.udfs, filter_func)
    if len(cands) == 0:
        raise ValueError("No function found for type: " + expect_dtype)
    strategy = self.args.udf_error_strategy
    # 根据错误策略选择函数，如果某一个函数出现了错误，减少函数的概率
    if strategy is None:
        picked = random.choice(cands)
    else:
        failures = []
        successes = []
        for udf in cands:
            failures.append(self.history_failures[udf.unique_id])
            successes.append(self.history_successes[udf.unique_id])
        weights = []
        if strategy == "drop":
            for k in range(len(cands)):
                w = (successes[k] + 1) ** 3
                if failures[k] > 0:
                    w = 0.00001
                else:
                    w = 100.0 / (w + (failures[k] + 1) ** 2)
                weights.append(w)
        else:  # down_sample
            for k in range(len(cands)):
                w = (successes[k] + 1) ** 3
                w = 100.0 / (w + (failures[k] + 1) ** 2)
                weights.append(w)
        total_weight = sum(weights)
        weights = [_ / total_weight for _ in weights]
        samples = list(np.random.multinomial(1, weights))
        picked = cands[samples.index(1)]
    self.picked_functions.append(picked)
    return picked