首页 > 解决方案 > 如何根据参数的数据类型不同地定义函数

问题描述

我正在尝试定义一个根据给定参数以不同方式工作的函数。

下面是一个谓词过滤器,对于给定的字符串 类型参数,它标记每个单词的词性,然后返回形容词、副词或动词。

但有时,给定的参数可能是我整个系统管道中的一个列表,当然,我可以定义另一个,但是我不想定义另一个完全相同的函数。

我可以 :

if type(sentence) == list -> blahblahblah and

如果类型(句子)== 字符串-> blahblahblah。

这很好,但我只是想知道会有另一种更好的方法来做到这一点。

有什么建议吗?

#defines predicate filter 

def pred_fl(sentence): 
    import nltk 

    ## Predicate Tags : 12 tags 
    tag_pred = ['JJ', 'JJR', 'JJS','RB','RBR', 'RBS', 'VB', 'VBD', 'VBG', 'VBN', 'VBP', 'VBZ']

    ## Noun Tags : 4 tags 
    tag_noun = ['NN','NNS','NNP','NNPS']

    # Pos tagging the input from the User_reply 
    tagged = nltk.pos_tag(sentence.split())
    
    reply_pred = []
    
    for i in range(len(tagged)):
        if tagged[i][1] in tag_pred:
            reply_pred.append(tagged[i][0])

    return reply_pred

标签: pythonfunction

解决方案


这正是重载方法和泛型函数的用途。

以下是如何使用singledispatch泛型函数来实现它:

@functools.singledispatch
def helper(arg):
    raise TypeError("I expected a type I know about, not some kind of Spanish Inquisition")

@helper.register(list)
def _(arg):
    # do listy stuff here

@helper.register(str)
def _(arg):
    # do stringy stuff here

def pred_fl(sentence): 
    # do setup that applies to all types here
    stuff = helper(sentence)
    # do stuff with stuff here

当然,我假设您的一堆“东西”对于这两种情况是相同的,并且它是您的“东西”的一小部分,可重构的部分必须有所不同。

如果整个事情最终变得不同,那么你真的应该有两个功能。

另一方面,如果不同的小部分是微不足道的——或者如果因为它与你正在做的其他事情密切相关而几乎不可能排除——你可能确实需要类型切换。但是通过检查isinstance(sentence, str),而不是检查type(sentence)

def pred_fl(sentence):
    # do setup that applies to all types here
    if isinstance(sentence, list):
        # do listy stuff that mutates a whole slew of local variables
    elif isinstance(sentence, str):
        # do stringy stuff that depends on a bunch of local state
    # do final stuff here

推荐阅读