在Python中检测re(regexp)对象

myk*_*hal 20 python regex types

我想知道什么是正确的pythonic向后兼容和向前兼容方法如何检查对象是否是编译re对象.

isinstance方法不能轻易使用,而生成的对象声称是_sre.SRE_Pattern对象:

>>> import re
>>> rex = re.compile('')
>>> rex
<_sre.SRE_Pattern object at 0x7f63db414390>
Run Code Online (Sandbox Code Playgroud)

但没有这样的:

>>> import _sre
>>> _sre.SRE_Pattern
AttributeError: 'module' object has no attribute 'SRE_Pattern'

>>> import sre
__main__:1: DeprecationWarning: The sre module is deprecated, please import re.
>>> sre.SRE_Pattern
AttributeError: 'module' object has no attribute 'SRE_Pattern'

>>> re.SRE_Pattern
AttributeError: 'module' object has no attribute 'SRE_Pattern'
Run Code Online (Sandbox Code Playgroud)

我不想使用duck typing(即检查某些特定方法的可用性),因为这可能会与其他一些类型冲突.

现在,我正在使用:

>>> RegexpType = type(re.compile(''))
>>> type(rex) == RegexpType
True
Run Code Online (Sandbox Code Playgroud)

但可能有更好的方法..

lvc*_*lvc 26

re._pattern_type 存在,似乎做你想做的事:

>>> isinstance(re.compile(''), re._pattern_type)
True
Run Code Online (Sandbox Code Playgroud)

但这不是一个好主意 - 根据Python惯例,以_开头的名称不是模块的公共API的一部分,也不是向后兼容性保证的一部分.因此,使用type(re.compile(''))是最好的选择 - 虽然注意到这也不能保证也能正常工作,因为re模块没有提到re.compile()返回的对象属于任何特定的类.

事实上,即使这是有保证的,最Pythonic和后向和前向兼容的方式将依赖于接口,而不是类型.换句话说,拥抱鸭子打字和EAFP,做这样的事情:

try:
     rex.match(my_string)
except AttributeError:
     # rex is not an re
else:
     # rex is an re
Run Code Online (Sandbox Code Playgroud)

  • 我不能同意依赖界面的建议.不是在这种情况下.许多对象可以具有可能完全不同的匹配属性.如果`rex`真的可以是任何东西,你不知道当你调用`rex.match`时会发生什么.当您知道对象具有执行某些预期或不执行某项操作的属性时,此策略有效,但当它具有该属性,没有该属性或具有可能具有相同名称的属性时,它也不起作用做一些完全不同的事. (6认同)
  • 请注意,从 Python 3.7 开始,`re._pattern_type` 被替换为 `re.Pattern`。 (4认同)