如何区分序列和映射
我想根据参数可能是类似地图的对象或类似序列的对象这一事实对参数执行操作。我知道没有任何策略对于类型检查来说是 100% 可靠的,但我正在寻找一个强大的解决方案。
基于这个答案,我知道如何确定某事是否是一个序列,我可以在检查对象是否是地图后进行此检查。
def ismap(arg):
# How to implement this?
def isseq(arg):
return hasattr(arg,"__iter__")
def operation(arg):
if ismap(arg):
# Do something with a dict-like object
elif isseq(arg):
# Do something with a sequence-like object
else:
# Do something else
因为序列可以看作是一个映射,其中键是整数,所以我应该尝试找到一个不是整数的键吗?或者也许我可以看看字符串表示形式?或者...?
更新
我选择了SilentGhost的答案,因为它看起来是最“正确”的答案,但根据我的需要,这是我最终实现的解决方案:
if hasattr(arg, 'keys') and hasattr(arg, '__getitem__'):
# Do something with a map
elif hasattr(arg, '__iter__'):
# Do something with a sequence/iterable
else:
# Do something else
本质上,我不想依赖ABC,因为有许多自定义类的行为类似于序列和字典,但仍然没有扩展 python 集合 ABC(请参阅@Manoj 评论)。我认为键属性(由删除他/她的答案的人提到)对于映射来说是足够好的检查。
扩展序列和映射 ABC 的类也适用于此解决方案。
I would like to perform an operation on an argument based on the fact that it might be a map-like object or a sequence-like object. I understand that no strategy is going to be 100% reliable for type-like checking, but I'm looking for a robust solution.
Based on this answer, I know how to determine whether something is a sequence and I can do this check after checking if the object is a map.
def ismap(arg):
# How to implement this?
def isseq(arg):
return hasattr(arg,"__iter__")
def operation(arg):
if ismap(arg):
# Do something with a dict-like object
elif isseq(arg):
# Do something with a sequence-like object
else:
# Do something else
Because a sequence can be seen as a map where keys are integers, should I just try to find a key that is not an integer? Or maybe I could look at the string representation? or...?
UPDATE
I selected SilentGhost's answer because it looks like the most "correct" one, but for my needs, here is the solution I ended up implementing:
if hasattr(arg, 'keys') and hasattr(arg, '__getitem__'):
# Do something with a map
elif hasattr(arg, '__iter__'):
# Do something with a sequence/iterable
else:
# Do something else
Essentially, I don't want to rely on an ABC because there are many custom classes that behave like sequences and dictionary but that still do not extend the python collections ABCs (see @Manoj comment). I thought the keys attribute (mentioned by someone who removed his/her answer) was a good enough check for mappings.
Classes extending the Sequence and Mapping ABCs will work with this solution as well.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
集合
抽象基类 (ABC)< /a>collections
abstract base classes (ABCs)序列有一个实现 + 运算符的
__add__
方法。映射没有这种方法,因为添加到映射需要键和值,而 + 运算符只有一个右侧。所以你可以尝试:
Sequences have an
__add__
method that implements the + operator. Maps do not have that method, since adding to a map requires both a key and a value, and the + operator only has one right-hand side.So you may try: