2012-05-09 2 views
3

git alias problem의 경우 파일 이름에서 하나의 파이썬 함수를 선택할 수 있기를 바랍니다. 예를 들면 : 당신이 하지 않은 라인을 찾을 때까지 당신이 /^(\s*)def $1[^a-zA-Z0-9]/ 파일에서 하나의 파이썬 함수를 선택하는 Bash 스크립트

  • 보관할 매칭에 일치하는 라인을 찾을 때

    1. 시작 필터링 : 알고리즘 측면에서

      ... 
          def notyet(): 
           wait for it 
      
          def ok_start(x): 
           stuff 
           stuff 
           def dontgettrickednow(): 
           keep going 
          #stuff 
           more stuff 
      
          def ok_stop_now(): 
      

      은 충분히 가까이 될 것이다 다음^\s*# 또는 ^/\1\s] (즉, 들여 쓰기가 가능한 주석 또는 이전 들여 쓰기보다 긴 들여 쓰기)

    (다음 기능을 수행하기 전에 데코레이터가 사용되는지는 신경 쓰지 않습니다. 결과는 사람의 독서를위한 것입니다.)

    나는 Awk (나는 거의 알지 못함)로 이것을하려했지만, 생각했던 것보다 조금 더 어려웠습니다. 처음에는 들여 쓰기 길이를 원래의 def 전에 저장하는 방법이 필요했습니다.

  • 답변

    3

    편도 사용 awk. 코드는 잘 설명되어 있으므로 이해하기 쉽기를 바랍니다.

    infile

    내용 :

    ... 
        def notyet(): 
         wait for it 
    
        def ok_start(x): 
         stuff 
         stuff 
         def dontgettrickednow(): 
         keep going 
        #stuff 
         more stuff 
    
        def ok_stop_now(): 
    

    내용 script.awk의 :

    BEGIN { 
         ## 'f' variable is the function to search, set a regexp with it. 
         f_regex = "^" f "[^a-zA-Z0-9]" 
    
         ## When set, print line. Otherwise omit line. 
         ## It is set when found the function searched. 
         ## It is unset when found any character different from '#' with less 
         ## spaces before it. 
         in_func = 0 
    } 
    
    ## Found function. 
    $1 == "def" && $2 ~ f_regex { 
    
         ## Get position of first 'd' in the line. 
         i = index($0, "d") 
    
         ## Sanity check. Never should success because the condition was 
         ## checked before. 
         if (i == 0) { 
           next 
         } 
    
         ## Get characters until matched index before, check that all of 
         ## them are spaces, and get its length. 
         indent = substr($0, 0, i - 1) 
         if (indent ~ /^[[:space:]]*$/) { 
           num_spaces = length(indent) 
         } 
    
         ## Set variable, print line and read next one. 
         in_func = 1 
         print 
         next 
    } 
    
    ## When we are inside the function, line doesn't begin with '#' and 
    ## it's not a blank line (only spaces). 
    in_func == 1 && $1 ~ /^[^#]/ && $0 ~ /[^[:space:]]/ { 
    
         ## Get how many characters there are until first non-space. The result 
         ## is the position of first non-blank, so substract one to get the number 
         ## of spaces. 
         spaces = match($0, /[^[:space:]]/) 
         spaces -= 1 
    
         ## If current indent is less or equal that the indent of function definition, then 
         ## end of function found, so end processing. 
         if (spaces <= num_spaces) { 
           in_func = 0 
         } 
    } 
    
    ## Self-explanatory. 
    in_func == 1 { 
         print 
    } 
    

    실행이 좋아 :

    : 다음과 같은 출력으로

    awk -f script.awk -v f="ok_start" infile 
    

    +0

    와우, 굉장 :) 나는 그것이 나의 실제 세계 기능에서 작동하는지 확인할 수있다. 흥미로운 점은 동일한 이름을 가진 두 개의 함수가있는 경우 (서로 다른 클래스에있을 경우 발생할 수 있음) 두 끝을 모두 반환한다는 것입니다. 그것이 의도 된 것인지 (또는 실제로 올바른 행동이 있어야하는지) - 좋은 결과 인 것 같습니다. –

    +0

    @SteveBennett : 방금 그 행동을 수정했습니다. 이제는 발견 된 첫 번째 기능 만 처리해야합니다. – Birei

    +0

    "같은 이름의 모든 함수를 선택"하는 것과 비슷합니다. 그렇지 않으면 같은 이름의 두 번째 함수에 어떻게 접근 할 수 있을지 잘 모르겠습니다. –

    3

    왜 파이썬이 그렇게하지 않을까요? 나는 inspection 모듈이 함수의 소스를 출력 할 수 있다고 생각한다. 따라서 모듈을 가져 와서 함수를 선택하고 검사하면된다. 잠깐만. 당신을위한 해결책을 놓치지 마십시오.

    OK.

    >>> def test(f): 
    ...  print 'arg:', f 
    ... 
    >>> test(1) 
    arg: 1 
    >>> inspect.getsource(test) 
    Traceback (most recent call last): 
        File "<stdin>", line 1, in <module> 
        File "C:\Python27\lib\inspect.py", line 699, in getsource 
        lines, lnum = getsourcelines(object) 
        File "C:\Python27\lib\inspect.py", line 688, in getsourcelines 
        lines, lnum = findsource(object) 
        File "C:\Python27\lib\inspect.py", line 529, in findsource 
        raise IOError('source code not available') 
    IOError: source code not available 
    >>> 
    

    을하지만, 사용 사례, 그것은 작동합니다 : 그것은 대화 형으로 정의 된 물건 작동하지 않습니다 inspect.getsource 기능을 밝혀 디스크에 저장되어 모듈의 경우.

    def test(f): 
        print 'arg:', f 
    
    def other(f): 
        print 'other:', f 
    

    을 그리고 비교이 대화 형 세션 : 예를 들어 내 test.py 파일을 가지고

    >>> import inspect 
    >>> import test 
    >>> inspect.getsource(test.test) 
    "def test(f):\n print 'arg:', f\n" 
    >>> inspect.getsource(test.other) 
    "def other(f):\n print 'other:', f\n" 
    >>> 
    

    을 그래서 ... 당신은 파이썬 소스 파일의 이름을 받아 간단한 파이썬 스크립트를 작성해야하고 함수/객체 이름을 인수로 사용합니다. 그런 다음 모듈을 가져 와서 기능을 검사하고이를 STDOUT으로 인쇄해야합니다.

    +0

    저는 여러분의 생각이 마음에 들지만, 파이썬이 전체 프로젝트를 구문 분석 할 수 있어야하는 것처럼 보입니다. 이는 단일 파일뿐만 아니라 모든 것을 검사한다는 것을 의미합니다. (그렇지 않으면 의존성이 깨 졌기 때문에 가져올 수 없습니다.) –

    +0

    오, 이런.물론, 파이썬 컴파일러 패키지가 도움이 될 수 있습니다 : http://docs.python.org/library/compiler.html -하지만 이것은 훨씬 더 많은 작업이 될 것입니다! –

    관련 문제