为你的函数起一个好的名字

没有人不希望为自己的孩子起一个好听的名字,要有好的寓意,要听起来顺耳,要与众不同,你的函数,也应该如此。好的函数命名,可以让使用者大致理解其功能,依据经验推理出应当传入什么样的参数,反之,坏的函数命名,就让人摸不到头脑甚至容易误导使用者。

最近,就遇到了这样一件事情。一个同事在使用jieba分词时,错误的使用了load_userdict函数来加载自定义词典。从根本上讲,没有认真阅读jieba的技术文档是导致错误使用该函数的主因,但这个函数的命名所产生的误导也不容忽视。

load_userdict只有一个参数,见到这个函数的第一反应,大多数人想到的是这个参数应当传入一个字典类型的数据,如果你也是这样,那么恭喜你,入坑了。如果你真的传入一个字典,这个函数不会报任何错误,甚至整个程序都会正常运行,这究竟是怎么一回事呢?

1. file-like object

让我们来看一下jieba维护者为这个函数添加的注释

def load_userdict(self, f):
        '''
        Load personalized dict to improve detect rate.

        Parameter:
            - f : A plain text file contains words and their ocurrences.
                  Can be a file-like object, or the path of the dictionary file,
                  whose encoding must be utf-8.

        Structure of dict file:
        word1 freq1 word_type1
        word2 freq2 word_type2
        ...
        Word type may be ignored
        '''

参数f 可以是文件的地址, 也可以是一个file-like object。如果是文件地址,则函数会使用open函数打开,这里有必要对file-like object做一下解释,在python中,如果一个对象实现了read() 和 write(), 那么它就是一个file-like object, 例如StringIO对象,建立起连接的socket对象,他们都是file-like object。

2. 传入一个字典

load_userdict,如果你没有认真看说明文档,而是凭借函数名称对函数的功能和参数类型进行揣测,那么,你很容得出函数接收字典类型参数的结论。更容易误导使用者犯错误的是,如果你真的传入一个字典,函数不会报错,加载的字典甚至可以”正常“使用。原因在于,函数内部并没有对传入参数的类型进行检查。

获取是由于巧合,尽管没有对参数类型进行检查,程序却可以正常执行而不报错,函数里对字典进行enumerate操作,是不会报错的,但由于数据格式的问题,不能正确解析一个词的freq和tag,下面这段代码可以正确运行,但是但每一个词的freq将会丢失

import jieba

a = '我爱好sparksql等spark技能'
map_ = {'sparksql':3,'spark':21}
jieba.load_userdict(map_)
sent = list(jieba.cut(a,cut_all=False))
print(sent)

我的这位同事对这个函数的命名颇有微词,并且坚持认为应该允许以字典的方式加载自定义词典,后来,我给了他一种变通的方法

import jieba
a = '我爱好sparksql等spark技能'
map_ = ['sparksql 3 n', 'spark 33 n']
jieba.load_userdict(map_)
sent = list(jieba.cut(a,cut_all=False))
print(sent)

尽管这样做也违背了这函数对参数的要求,但是可以正常加载自定义词典

3. 建议修改这个函数名称

鉴于这个函数的名称具有误导性,我建议对名称进行修改

def load_userdict_file(self, f):

这样一来,大家都会明白这个函数需要传入的是一个file文件,具体是文件的路径,还是文件对象,有了这样的函数名称,自然会引导大家来查看技术文档。另一方面,在函数内对参数类型进行检查,如果是字符串,则判断文件路径是否存在,如果是文件对象,则直接使用。

扫描关注, 与我技术互动

QQ交流群: 211426309

加入知识星球, 每天收获更多精彩内容

分享日常研究的python技术和遇到的问题及解决方案