我正在使用从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)
是递归的,因此我不希望在递归调用函数后将“自我”作为第一个参数,这对于常规实例方法将是这种情况。
我有很多静态方法正在使用,但是我在很多地方都读过,所以经常使用它们可能不是一个好习惯。我还认为我可以使它们成为模块函数,但我希望它们与类联系在一起。
问题2:如何将参数keylist
传递给self._get_key_list(d,keylist)
,而不是如何在递归函数中初始化一个空列表并进行更新?在内部对其进行初始化会每次将其重置为[]。
答案 0 :(得分:1)
我将消除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
答案 1 :(得分:0)
没有充分的理由将类中的递归函数设为静态方法,除非要在实例的上下文之外调用它。
要初始化参数,我们通常在参数列表中为其分配一个默认值,但是如果该参数需要是可变对象(例如在这种情况下为空列表),则需要将其默认设置为None并进行初始化它放在函数中,这样列表引用就不会在下一次调用中重用:
class Myclass(object):
def _get_key_list(self, d, keylist=None):
if keylist is None:
keylist = []
for key, value in d.iteritems():
keylist.append(key)
if isinstance(value, dict):
self._get_key_list(d.get(key), keylist)
return list(set(keylist))
def diff(self, dict2):
all_keys1 = self._get_key_list(self.d)
all_keys2 = self._get_key_list(dict2)
... # More code