首页 > 解决方案 > 类中递归函数的静态方法?

问题描述

我正在使用从 YAML 对象获得的 Python (2.7) 上的嵌套字典,我有几个问题一直试图通过阅读得到答案,但没有成功。我对 Python 有点陌生。

最简单的功能之一是读取整个字典并输出其中存在的所有键的列表。我在开头使用下划线,因为这个函数后来被类中的其他人使用。

    class Myclass(object):

    @staticmethod
    def _get_key_list(d,keylist):
        for key,value in d.iteritems():
            keylist.append(key)
            if isinstance(value,dict):
                Myclass._get_key_list(d.get(key),keylist)
        return list(set(keylist))

    def diff(self,dict2):
        keylist = []
        all_keys1 = self._get_key_list(self.d,keylist)
        all_keys2 = self._get_key_list(dict2,keylist)
        ... # More code

问题1:这是正确的方法吗?我不确定出于这个原因使用静态方法是否是一种好习惯。由于self._get_key_list(d,keylist)是递归的,一旦函数被递归调用,我不希望“self”成为第一个参数,这是常规实例方法会发生的情况。

我有一堆我正在使用的静态方法,但我在很多地方都读过,它们在大量使用时可能不是很好的做法。我还认为我可以使它们成为模块函数,但我希望它们与类相关联。

问题 2:我怎样才能在递归函数中初始化一个空列表并更新它,而不是将参数传递keylist给?self._get_key_list(d,keylist)在内部初始化它会将其重置为 [] 每次。

标签: pythonpython-2.7

解决方案


我将消除keylist作为一个明确的论点:

def _get_keys(d):
    keyset = set()
    for key, value in d.iteritems():
        keylist.add(key)
        if isinstance(value, dict):
            keylist.update(_get_key_list(value))
    return keyset

如果调用者真的需要一个列表,而不是一个可迭代的,让调用者将集合转换为一个列表。

通常,几乎没有理由将某些东西声明为静态方法而不是类外的函数。

如果您担心效率(例如,从字典中获取大量重复键),您可以返回通过调用将单个集合/列表作为显式参数进行线程化,但不要使其成为可选的;只要求初始调用者提供要更新的集合/列表。为了强调第二个参数将被改变,只需None在函数返回时返回。

def _get_keys(d, result):
    for key, value in d.iteritems():
        result.add(key)
        if isinstance(value, dict):
            _get_keys(value, result)

result = set()
_get_keys(d1, result)
_get_keys(d2, result)
# etc

推荐阅读