python中已编译的正则表达式对象的类型

Jee*_*Kim 64 python regex types

python中编译的正则表达式的类型是什么?

特别是,我想评估

isinstance(re.compile(''), ???)
Run Code Online (Sandbox Code Playgroud)

为了内省目的,这是真的.

我有一个解决方案,有一些全局常数REGEX_TYPE = type(re.compile('')),但它似乎并不优雅.

编辑:我想这样做的原因是因为我有字符串列表和编译的正则表达式对象.我希望将一个字符串与列表"匹配"

  • 对于列表中的每个字符串,尝试检查字符串是否相等.
  • 对于列表中的每个正则表达式,尝试检查字符串是否与给定模式匹配.

我想出的代码是:

for allowed in alloweds:
    if isinstance(allowed, basestring) and allowed == input:
        ignored = False
        break
    elif isinstance(allowed, REGEX_TYPE) and allowed.match(input):
        ignored = False
        break
Run Code Online (Sandbox Code Playgroud)

fly*_*eep 43

Python 3.5引入了该typing模块.其中包括:typing.Patterna _TypeAlias.

从Python 3.6开始,您可以简单地执行以下操作:

from typing import Pattern

my_re = re.compile('foo')
assert isinstance(my_re, Pattern)
Run Code Online (Sandbox Code Playgroud)

在3.5中,曾经有一个错误要求你这样做:

assert issubclass(type(my_re), Pattern)
Run Code Online (Sandbox Code Playgroud)

根据文档和测试套件,不保证可以使用.

  • 我不得不使用`from typing import Pattern`来访问`Pattern`. (6认同)
  • 根据链接的问题,这个错误似乎在2016-09-27之前修复. (2认同)

Jea*_*one 34

如果没有明确指定某种类型的东西,使用type内置函数在运行时发现答案没有错:

>>> import re
>>> retype = type(re.compile('hello, world'))
>>> isinstance(re.compile('goodbye'), retype)
True
>>> isinstance(12, retype)
False
>>> 
Run Code Online (Sandbox Code Playgroud)

在运行时发现类型可以保护您不必访问私有属性以及将来对返回类型的更改.在type这里使用没有什么不优雅,尽管可能有一些不太优雅的想要知道这种类型.

  • 使用此方法发现的类型并不总是正确的 - 实现可能使用一种或多种类型来支持给定的功能.与正则表达式不太一样,但是一些工厂现在可能返回一种类型,之后会返回多种类型.但这只是通过检查类型来打破鸭子打字支持期望的另一种形式. (11认同)
  • @Rosh:对于OP的问题,这是一个实用的答案.让 - 保罗确实说这最终不是一个好习惯,但作为直接回答,这是一个很好的做法.++ (4认同)

ale*_*mol 21

可以将编译的正则表达式与're._pattern_type'进行比较

import re
pattern = r'aa'
compiled_re = re.compile(pattern)
print isinstance(compiled_re, re._pattern_type)

>>True
Run Code Online (Sandbox Code Playgroud)

至少在版本2.7中给予真实


bgw*_*bgw 16

免责声明:这不是针对您的特定需求的直接答案,而是作为替代方法可能有用的东西


您可以保持duck typing的理想,并使用它hasattr来确定对象是否具有您想要使用的某些属性.例如,您可以执行以下操作:

if hasattr(possibly_a_re_object, "match"): # Treat it like it's an re object
    possibly_a_re_object.match(thing_to_match_against)
else:
    # alternative handler
Run Code Online (Sandbox Code Playgroud)


Joh*_*hin 10

预防胜于治疗.首先不要创建这样的异构列表.拥有一允许的字符串和已编译的正则表达式对象列表.这应该使您的检查代码看起来更好并且运行得更快:

if input in allowed_strings:
    ignored = False
else:
    for allowed in allowed_regexed_objects:
        if allowed.match(input):
            ignored = False
            break
Run Code Online (Sandbox Code Playgroud)

如果您无法避免创建此类列表,请查看是否有机会检查它并构建两个替换对象.

  • 这个答案是建设性的,这很好,但它没有回答原来的问题. (2认同)

tri*_*eee 7

作为多态性的一个例子,另一种解决方案是创建实现常用方法的包装类.

class Stringish (str):
    def matches (self, input):
        return self == input

class Regexish (re):
    def matches (self, input):
        return self.match(input)
Run Code Online (Sandbox Code Playgroud)

现在,您的代码可以迭代一个alloweds包含对象的列表,完全透明地实例化这两个类中的任何一个:

for allowed in alloweds:
    if allowed.matches(input):
        ignored = False
        break
Run Code Online (Sandbox Code Playgroud)

另请注意一些代码重复是如何消失的(尽管您的原始代码可能已被重构以单独修复).