解析:Python 中 class 方法的函数继承

Parsing: functional inheritance for class methods in Python

在某些情况下,我正在尝试为一种搜索语言编写解析器。目前我有一堆 class 方法来接受满足特定条件的令牌,但是它们的通用 structure/format 似乎可以用(新编写的)方法 _accept_generic.

class Parser(object):
    ...
    def now(self):
        # now = self._tokens[self._pos] if not self.end() else None
        # print(now, self._pos)
        return self._tokens[self._pos] if not self.end() else None

    def end(self):
        return self._pos == self._length
    
    def step(self):
        self._pos += 1

    def _accept_generic(self, criterion):
        if not self.end():
            if criterion:
                self.step()
                return True
        return False
    
    def _accept(self, char):
        return self._accept_generic(self.now() == char)
        # if not self.end():
        #     if self.now() == char:
        #         self.step()
        #         return True
        # return False
        
    def _accept_re(self, regex):
        return self._accept_generic(regex.match(self.now()))
        # if not self.end():
        #     if regex.match(self.now()):
        #         self.step()
        #         return True
        # return False
    
    def _accept_any_res(self, *regexes):
        return self._accept_generic(any([r.match(self.now()) for r in regexes]))
        # if any([r.match(self.now()) for r in regexes]):
        #     self.step()
        #     return True
        # return False

    def _accept_all_res(self, *regexes):
        return self._accept_generic(all([r.match(self.now()) for r in regexes]))
        # if all([r.match(self.now()) for r in regexes]):
        #     self.step()
        #     return True
        # return False

当前代码的问题是它会抛出错误(因为标准是在函数参数中计算的,而不是在 if 语句 if not self.end() 中计算的)。有没有办法使用例如functools 允许函数继承泛型的结构,能够在子函数的代码中指定新参数,而不必重复编写相同的代码块? functools.partialmethods 并没有真正满足我的要求。

您可以将标准设为函数并将其传递给 _accept_generic:

def _accept(self, char):
        return self._accept_generic(lambda c=char: self.now() == c)

然后调用_accept_generic:

def _accept_generic(self, criterion):
        if not self.end():
            if criterion():
                self.step()
                return True
        return False