Python2上的`setattr()``_sre.SRE_Pattern`

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Python2上的`setattr()``_sre.SRE_Pattern`相关的知识,希望对你有一定的参考价值。

我基本上试图通过尝试将一个fullmatch方法添加到Python2 re编译模式来尝试兼容py2 / 3。

我见过https://stackoverflow.com/a/2982/2694385关于如何向现有实例添加属性。我正在创建https://stackoverflow.com/a/30212799/2694385中给出的方法。

示例代码

import re
import six


regex = re.compile('some pattern')  # Better if we keep this same

if six.PY2:
    def fullmatch(self_regex, string, flags=0):
        return self_regex.match(string, flags=flags)

    regex = re.compile(r'(?:' + regex.pattern + r')', flags=regex.flags)

    import types

    bound = types.MethodType(fullmatch, regex)
    # AttributeError here. None of the following three lines work
    regex.fullmatch = bound
    regex.__setattr__('fullmatch', bound)
    setattr(regex, 'fullmatch', bound)
答案

这不会起作用 - 在C端创建正则表达式对象,它们不代表您的常规实例,因此您无法在Python中修改其签名。例如,如果您尝试扩展_sre.SRE_Pattern

import _sre

class CustomPattern(_sre.SRE_Pattern): pass

你会得到一个AttributeError抱怨_sre模块中不存在这样的对象。如果你试图欺骗它:

import re

tmp_pattern = re.compile("")
sre_pat = type(tmp_pattern)

class CustomPattern(sre_pat): pass

它会给你一个TypeError抱怨_sre.SRE_Pattern(现在'临时'存在,因为它是临时创建)不是一个可接受的基类型。

你可以做的是在re模块周围创建一个完整的包装器(或者至少添加缺少的结构)并处理Python方面的Python版本差异,尽管我认为它不值得。

附:如果你没有在其他任何地方使用six,没有理由只检查你的Python版本 - 你可以使用sys.version_info.major < 3代替。

另一答案

请参阅nlpia.regexes.Pattern,了解类似于您想要的东西 - 使用_sre.Pattern方法的fullmatch()的Frankenstein混搭。这种猴子修补“继承”方法适用于Python 2和3。

import re
import regex

class Pattern:
    """ "Inherits" _sre.SRE_Pattern and adds .fullmatch() method

    >>> pattern = Pattern('Aaron[ ]Swartz')
    >>> pattern.match('Aaron Swartz')
    <_sre.SRE_Match object; span=(0, 12), match='Aaron Swartz'>
    >>> pattern.fullmatch('Aaron Swartz!!')
    >>> pattern.match('Aaron Swartz!!')
    <_sre.SRE_Match object; span=(0, 12), match='Aaron Swartz'>
    """
    def __init__(self, pattern):
        self._compiled_pattern = re.compile(pattern)
        for name in dir(self._compiled_pattern):
            if not name in set(('__class__', '__init__', 'fullmatch')):
                attr = getattr(self._compiled_pattern, name)
                setattr(self, name, attr)

def fullmatch(self, *args, **kwargs):
    return regex.fullmatch(self._compiled_pattern.pattern, *args, **kwargs)

以上是关于Python2上的`setattr()``_sre.SRE_Pattern`的主要内容,如果未能解决你的问题,请参考以下文章

菜鸟容易中的招__setattr__

Python 元类:为啥在类定义期间不调用 __setattr__ 来设置属性?

访问全局变量时模块的 __setattr__ 和 __getattr__

错误:_sre.SRE_Pattern 不可迭代,我正在使用 re.compile() 通过比较起始值并获取此错误来获取字符串

__setattr__和__delattr__和__getattr__

python基础之类的__setattr__,__delattr__,__getattr__