Python 和类似字典的对象
我需要一个用于字典的 python 3.1 深度更新函数(该函数将递归更新父字典内的子字典)。
但我认为,将来我的函数可能必须处理行为类似于字典但实际上并非如此的对象。 此外,我想避免使用 isinstance
和 type
(因为它们被认为是不好的,因为我可以继续阅读几乎每个 Pythonista 的博客)。
但鸭子类型是 Python 哲学的一部分,那么我如何检查一个对象是否类似于字典呢?
谢谢!
编辑:感谢大家的回答。 为了以防万一,我编码的函数可以在这个地方找到:http://blog. Cafeaumiel.com/public/python/dict_deep_update.py
I need a python 3.1 deep update function for dictionaries (a function that will recursively update child dictionaries that are inside a parent dictionary).
But I think, in the future, my function could have to deal with objects that behave like dictionaries but aren't. And furthermore I want to avoid using isinstance
and type
(because they are considered bad, as I can read on almost every Pythonista's blog).
But duck typing is part of Python's philosophy, so how could I check if an object is dictionary-like?
Thanks!
Edit : Thank all for the answers. Just in case, the function I coded can be found at this place : http://blog.cafeaumiel.com/public/python/dict_deep_update.py
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
查看集合模块中的(3.x 中的新增)抽象基类 (ABC):
http://docs.python.org/3.1/library/collections.html
我会考虑使用 isinstance 与 Mapping 进行检查,如下所示:
然后,如果您创建自己的类似 dict 的类,请创建 collections.Mapping其基地之一。
另一条路线是尝试捕获字典操作的任何异常,但是通过您正在讨论的递归,我宁愿首先检查基本类型,而不是处理弄清楚什么是 dict 或 subdict 或其他 dict 成员不在那里抛出异常。
编辑添加:检查映射 ABC 而不是检查 dict 的好处是,相同的测试将适用于类似 dict 的类,无论它们是否是 dict 的子类,因此它更灵活,以防万一。
Check out the (new in 3.x) abstract base classes (ABC's) in the collections module:
http://docs.python.org/3.1/library/collections.html
I would consider checking with isinstance against Mapping like in the following:
Then, if you make your own dict-like class, make collections.Mapping one of its bases.
The other route is trying and catching whatever exceptions for the dictionary operations, - but with the recursion you're talking about, I'd rather check against the base type first than handle figuring out what dict or subdict or other dict member was or was not there to throw an exception.
Editing to add: The benefit of checking against the Mapping ABC instead of against dict is that the same test will work for dict-like classes regardless of whether or not they subclass dict, so it's more flexible, just in case.
如果您还必须处理行为类似于字典但不是 dict 子类的自定义类,则可以使用 getattr 来获取所需的函数。
If you also have to handle custom classes that behave like dictionaries but aren't subclassed from dict, you can use getattr to get the function you require.
那么,要递归更新字典,您必须调用“items”方法来迭代它。
所以我建议,你只需这样做:
Well, to update recursively a dictionary, you must call the 'items' method to iterate on it.
So I suggest, you just do :
使用
isinstance
,它没有任何问题,并且通常在需要递归的代码中使用。如果“类似字典”是指对象的类继承自
dict
,则isinstance
也将返回True
。use
isinstance
, there is nothing wrong with it and it's routinely used in code requiring recursion.If by dictionary-like you mean the object's class inherit from the
dict
,isinstance
will also returnTrue
.鸭子类型是你做你想做的事情的地方,并在你的对象没有按照你期望的方式运行时处理后果。
您想检查某些内容是否类似于字典,如果是则更新它,对吗? 只需调用对象的 update 方法,如果没有该方法,则处理收到的异常。
当然,如果您处理的自定义类对象具有完全执行其他操作的更新方法,那么这将失败 - 我不太确定如何处理这个问题。
Duck typing is where you do what you want to do, and deal with the fallout if your objects don't behave the way you expected them to.
You want to check if something is dict-like, and update it if it is, right? Just call the object's update method, and handle the Exception you get if there is no such method.
Of course, this will fall flat if you deal with custom class objects which have update methods that do something else entirely -- I'm not quite sure how to deal with that.
我喜欢检查 '__setitem__' 魔术方法...这就是允许 foo['bar'] = baz 行为的原因。
这是 python 2.7 文档
I like to check for the '__setitem__' magic method... this that is what allows the foo['bar'] = baz behavior.
Here is the python 2.7 docs