Python和类字典对象
我需要一个用于字典的python 3.1深度更新函数(一个递归更新父字典中的子字典的函数) 但我认为,在未来,我的函数可能必须处理行为类似于字典但不是字典的对象。此外,我想避免使用Python和类字典对象,python,dictionary,duck-typing,Python,Dictionary,Duck Typing,我需要一个用于字典的python 3.1深度更新函数(一个递归更新父字典中的子字典的函数) 但我认为,在未来,我的函数可能必须处理行为类似于字典但不是字典的对象。此外,我想避免使用isinstance和类型(因为它们被认为是不好的,因为我几乎可以在每一个Pythonista的博客上读到) 但是duck类型是Python哲学的一部分,所以我如何检查对象是否像字典一样 谢谢 编辑:谢谢大家的回答。为了以防万一,我编写的函数可以在这里找到:使用isinstance,它没有任何问题,并且在需要递归的代码
isinstance
和类型
(因为它们被认为是不好的,因为我几乎可以在每一个Pythonista的博客上读到)
但是duck类型是Python哲学的一部分,所以我如何检查对象是否像字典一样
谢谢
编辑:谢谢大家的回答。为了以防万一,我编写的函数可以在这里找到:使用
isinstance
,它没有任何问题,并且在需要递归的代码中经常使用它
如果您所说的dictionary like是指对象的类继承自dict
,isinstance
也将返回True
>>> class A(dict):
pass
>>> a = A()
>>> isinstance(a, dict)
True
Duck类型是你做你想做的事情的地方,如果你的对象没有按你所期望的方式运行,那么你可以处理它带来的后果 您想检查某个内容是否与dict类似,如果是,则进行更新,对吗?只要调用对象的update方法,如果没有这样的方法,就可以处理得到的异常 当然,如果您处理的自定义类对象具有完全执行其他操作的更新方法,则这一点将变得平淡无奇。我不太确定如何处理这一点。查看collections模块中的(3.x中新增的)抽象基类(ABC):
我会考虑用IS实例检查映射,比如如下:
>>> import collections
>>> isinstance({},collections.Mapping)
True
然后,如果您创建了自己的类似dict的类,那么就创建集合。映射它的一个基
另一种方法是尝试并捕获字典操作的任何异常,-但是对于您所说的递归,我宁愿先检查基类型,而不是处理确定什么dict或subct或其他dict成员在那里抛出异常
编辑添加:对照映射ABC而不是dict进行检查的好处是,相同的测试将适用于类似dict的类,无论它们是否是dict的子类,因此它更灵活,以防万一。如果您还必须处理行为类似字典但不是dict的子类的自定义类,您可以使用getattr获取所需的函数
# loop
# ... more code
someObject = getObject(..)
try:
getattr(someObject, "update")("someValue")
except AttributeError:
# Wasn't a type we can handle
要递归更新字典,必须调用“items”方法对其进行迭代 所以我建议,你只要:
try :
for key, value in data.items() :
# recursive call
except AttributeError :
# handling the trouble
我想检查“\uuuuu setitem\uuuu”魔术方法。。。这就是允许foo['bar]=baz行为的原因
if getattr(obj, '__setattr__'):
obj[key] = val
以下是绝对正确的:ABC让您“针对接口编程,而不是实现”,正如Gof4所敦促的那样Gof4是“四人帮”的缩写,这本书的作者通常被称为“四人帮”,因为这比说出他们所有的名字要容易:是的,顺便说一句,我强烈推荐这本书,尽管我的同事乔·格雷戈里奥也强烈反对(他声称Python中没有DPs——呵呵——希望我们能在本地Python用户组未来的某个会议上就这个问题进行辩论!-)。这个例子应该一直适用于Python 2.4(当collections模块出现时)。它在Python 2.7上工作。请参见Py 2和Py 3.8。Support始终对博客上的笼统陈述持保留态度。我非常喜欢duck类型和“请求原谅比允许更容易”的说法方法,但请参阅PEP 3119关于ABC的内容,如下面我的回答中所述,以获得更细致的讨论:--您可以在此处测试所述方法的存在性。fac是我不想针对dict类而针对其接口进行编码:)我不使用dict类中的update方法。相反,我手动遍历字典,当一个值是一个类似字典的对象时,我尝试递归调用我的函数来更新它。列表还有
\uuuuuuu setitem\uuuuuu
和\uuuu getitem\uuuuu
。