使用结构模式匹配,如何编写匹配哈希类型实例的案例?
我尝试过:
for obj in [], (), set(), frozenset(), 10, None, dict():
match obj:
case object(__hash__=_):
print('Hashable type: ', type(obj))
case _:
print('Unhashable type: ', type(obj))
但是,这得到了错误的答案,因为每个类型都定义了它是否可哈希:
Hashable type: <class 'list'>
Hashable type: <class 'tuple'>
Hashable type: <class 'set'>
Hashable type: <class 'frozenset'>
Hashable type: <class 'int'>
Hashable type: <class 'NoneType'>
Hashable type: <class 'dict'>
集合中的可哈希抽象基类。abc可以通过测试识别实现哈希的类型,如isinstance(obj,Hashable)或issubclass(cls,Hashable)。
根据PEP 622,对于类模式,“匹配是否成功由is实例调用的等价物决定。”
因此,您可以直接在类模式中使用Hasable:
from collections.abc import Hashable
for obj in [], (), set(), frozenset(), 10, None, dict():
match obj:
case Hashable():
print('Hashable type: ', type(obj))
case _:
print('Unhashable type:', type(obj))
这将生成所需的答案:
Unhashable type: <class 'list'>
Hashable type: <class 'tuple'>
Unhashable type: <class 'set'>
Hashable type: <class 'frozenset'>
Hashable type: <class 'int'>
Hashable type: <class 'NoneType'>
Unhashable type: <class 'dict'>
Hashable只处理最外层对象的类型。它报告了“对象类型实现哈希”意义上的哈希性,这就是我们通常所说的“元组是可哈希的”。这也是抽象基类和静态类型使用的相同含义。
尽管哈希可检测类型是否实现了_hash_,但它无法知道哈希实际做了什么,是否会成功,或者是否会给出一致的结果。
例如,散列给出了浮动('NaN')
的不一致结果。元组和frozenset通常是可散列的,但如果它们的组件值不可散列,则无法散列。一个类可以定义__hash__
以始终引发异常。
RaymondHettinger的答案在有限的情况下有效,但它在诸如<代码>列表
(类型对象本身)之类的输入上失败,即使是<代码>列表,它也是可散列的__hash\uuuuu是None(无),输入类似于([1,2],[3,4])
,即使是tuple(元组),也是不可损坏的__hash\uuuu不是None。
检测对象是否可散列的最可靠方法总是尝试散列它。如果您想在匹配
语句中执行此操作,最简单的方法是编写一个保护:
def hashable(x):
try:
hash(x)
except TypeError:
return False
else:
return True
match x:
case _ if hashable(x):
...
...
这只是直接调用hash(x)并查看它是否工作,而不是尝试执行结构检查。
如果您需要哈希并希望避免双重计算,您可以保存hash(x)
结果:
def try_hash(x):
try:
return hash(x)
except TypeError:
return None
match x:
case _ if (x_hash := try_hash(x)) is not None:
...
...
我一直在将if-elif链转换为结构模式匹配,但在反向测试中遇到了困难。 很容易生成与任何支持的模式(文本、类、映射、序列等)匹配的案例。我如何证明一个否定的匹配? 例如,当对象的类型不匹配时,我需要强制它:
我无法运行此代码: 我在Python中找不到匹配关键字。 我在这里找到的:https://www.python.org/dev/peps/pep-0622/#the-match语句 有什么想法吗?
模式有两种形式:refutable(可反驳的)和 irrefutable(不可反驳的)。能匹配任何传递的可能值的模式被称为是 不可反驳的(irrefutable)。一个例子就是 语句中的 x,因为 x 可以匹配任何值所以不可能会失败。对某些可能的值进行匹配会失败的模式被称为是 可反驳的(refutable)。一个这样的例子便是 if let Some(x) = a_value 表达式中的 Some
我有一个字符串,我正试图根据几个regex模式验证它,我希望由于模式匹配在3.10中可用,我可以使用它来代替创建if-else块。 考虑一个字符串'validateString',其可能的值1021102,1.25.32string021。 我尝试的代码如下所示。 对于正则表达式1、2和3,我尝试了字符串正则表达式模式,还重新设置了。编译对象,但它似乎不起作用。 我一直试图在互联网上找到这方面的例
我有通过查找属性来检查命名元组和数据类的代码: 如何使用Python 3.10的匹配/大小写结构模式匹配来表达这一点?