2

这是 python 2.7 的一个普遍问题pyparsing(在 3 中它工作得很好)。一般结构是这样的:

class SomeParser(object):

    def some_action(self, string, loc, tok):
         print("action")

    def gramma(self):
          ...pyparsing gramma for some 

             language....
         some_rule = (token + token2).setParseAction(self.some_action)
         return some_rule

     def parse(self, string):
         self.gramma().parseString(string)
         return True

在 python3pyparsing中工作得很好,但在 2.7 中我得到了

Parsing error : some_action() takes exactly 4 arguments (1 given)

我的问题是如何使它在两个版本中都起作用?

编辑:经过一些测试,我发现这是一般问题,不仅仅是类方法。

4

1 回答 1

1

我想我发现了一个问题(在朋友的帮助下),它在pyparsing1.5.6 中,它的_trim_arity函数试图猜测 func insetParseAction(func)接受的参数数量。我将其更改为:

if not _PY3K:                                                                                                                                                               
    def _trim_arity(func, maxargs=2):                                                                                                                                                 
        limit = [0]                                                                                                                                                                   
        def wrapper(*args):                                                                                                                                                           
            while 1:                                                                                                                                                                  
                try:                                                                                                                                                                  
                    return func(*args[limit[0]:])                                                                                                                                     
                except TypeError:                                                                                                                                                     
                    if limit[0] <= maxargs:                                                                                                                                           
                        limit[0] += 1                                                                                                                                                 
                        continue                                                                                                                                                      
                    raise                                                                                                                                                             
        return wrapper                                                                                                                                                                
    else:                                                                                                                                                                                 
        def _trim_arity(func, maxargs=2):                                                                                                                                                 
            limit = maxargs                                                                                                                                                             
            def wrapper(*args):                                                                                                                                                                                                                                                                                                             
                #~ nonlocal limit                                                                                                                                                         
                while 1:                                                                                                                                                                  
                    try:                                                                                                                                                                  
                        return func(*args[limit:])                                                                                                                                        
                    except TypeError:                                                                                                                                                     
                        if limit:                                                                                                                                                         
                            limit -= 1                                                                                                                                                    
                            continue                                                                                                                                                      
                        raise                                                                                                                                                             
            return wrapper   

到:

if not _PY3K and False:                                                                                                                                                               
    def _trim_arity(func, maxargs=2):                                                                                                                                                 
        limit = [0]                                                                                                                                                                   
        def wrapper(*args):                                                                                                                                                           
            while 1:                                                                                                                                                                  
                try:                                                                                                                                                                  
                    return func(*args[limit[0]:])                                                                                                                                     
                except TypeError:                                                                                                                                                     
                    if limit[0] <= maxargs:                                                                                                                                           
                        limit[0] += 1                                                                                                                                                 
                        continue                                                                                                                                                      
                    raise                                                                                                                                                             
        return wrapper                                                                                                                                                                
    else:                                                                                                                                                                                 
        def _trim_arity(func, maxargs=2):                                                                                                                                                 
            # limit = maxargs                                                                                                                                                             
            def wrapper(*args):                                                                                                                                                           
                limit = maxargs                                                                                                                                                           
                #~ nonlocal limit                                                                                                                                                         
                while 1:                                                                                                                                                                  
                    try:                                                                                                                                                                  
                        return func(*args[limit:])                                                                                                                                        
                    except TypeError:                                                                                                                                                     
                        if limit:                                                                                                                                                         
                            limit -= 1                                                                                                                                                    
                            continue                                                                                                                                                      
                        raise                                                                                                                                                             
            return wrapper   

不是很优雅,但我可以看到trunk在 pyparsing 版本中它已经修复了。

于 2012-10-23T13:49:53.960 回答