2

これは、pyparsingPython 2.7の一般的な問題です(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

python3では問題なくpyparsing動作しますが、2.7では

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

私の質問は、両方のバージョンでそれを機能させる方法ですか?

編集:いくつかのテストの後、クラスメソッドだけでなく、一般的な問題であることがわかりました。

4

1 に答える 1

1

問題を (友人の助けを借りて) 見つけたと思います。これはpyparsing1.5.6 にあり、関数が受け入れ_trim_arityている引数の数を推測しようとするその関数です。setParseAction(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   

あまりエレガントではありませんが、trunkpyparsing のバージョンでは既に修正されていることがわかります。

于 2012-10-23T13:49:53.960 に答える