2017-03-20 2 views
1

필자는 Tkinter GUI에서이 스크립트를 호출했습니다. 내 함수 중 하나에서 변수 중 하나를 호출 할 수 없으며 그 이유를 이해할 수 없습니까?Python 모듈 NameError

NameError 나는 'framevalues'이 내 태그 기능 중 하나를 트리거하기 위해 키 누르기를 할 때 정의되어 있지 않습니다.

미리 감사드립니다.

import cv2 
import tkinter as tk 
from tkinter.filedialog import askopenfilename 


def main(): 
    framevalues = [] 
    count = 1 
    selectedvideo = askopenfilename() 
    selectedvideostring = str(selectedvideo) 
    cap = cv2.VideoCapture(selectedvideo) 
    length = int(cap.get(cv2.CAP_PROP_FRAME_COUNT)) 

    while (cap.isOpened()): 
     ret, frame = cap.read() 

     # check if read frame was successful 
     if ret == False: 
       break 
     # show frame first 
     cv2.imshow('frame',frame) 

     # then waitKey 
     frameclick = cv2.waitKey(0) & 0xFF 

     if frameclick == ord('a'): 
      swingTag(cap) 

     elif frameclick == ord('r'): 
      rewindFrames(cap) 

     elif frameclick == ord('s'): 
      stanceTag(cap) 

     elif frameclick == ord('d'): 
      unsureTag(cap) 

     elif frameclick == ord('q'): 
      with open((selectedvideostring + '.txt'), 'w') as textfile: 
       for item in framevalues: 
        textfile.write("{}\n".format(item)) 
      break 

     else: 
      continue 

    cap.release() 
    cv2.destroyAllWindows() 

def stanceTag(cap):  
    framevalues.append('0' + ' ' + '|' + ' ' + str(int(cap.get(1)))) 
    print (str(int(cap.get(1))), '/', length) 
    print(framevalues) 

def swingTag(cap): 
    framevalues.append('1' + ' ' + '|' + ' ' + str(int(cap.get(1)))) 
    print (str(int(cap.get(1))), '/', length) 
    print(framevalues) 

def unsureTag(cap): 
    framevalues.append('-1' + ' ' + '|' + ' ' + str(int(cap.get(1)))) 
    print (str(int(cap.get(1))), '/', length) 
    print(framevalues) 

def rewindFrames(cap): 
    cap.set(1,((int(cap.get(1)) - 2))) 
    print (int(cap.get(1)), '/', length) 
    framevalues.pop() 
    print(framevalues) 






if __name__ == '__main__': 
    # this is called if this code was not imported ... ie it was directly run 
    # if this is called, that means there is no GUI already running, so we need to create a root 
    root = tk.Tk() 
    root.withdraw() 
    main() 

답변

3

framevaluesmain() 내에 정의 된 로컬 변수이고, 따라서 다른 기능 내부 보이지 않는다. 전역으로 만들 수 있습니다. 즉, main() 전에 정의하거나 main()에서 정상 함수 매개 변수로 다른 함수로 전달할 수 있습니다.

def main(): 
    ... 
    if frameclick == ord('a'): 
     swingTag(cap, framevalues) # pass it as a parameter 
    ... 
... 
def swingTag(cap, framevalues): 
    framevalues.append(...) # now you are using local framevalues passed as parameter 
+0

문제가 해결되었습니다. tkinter 파일 선택 프롬프트를 자동로드하지 않고 GUI에서 스크립트를 실행할 수 있도록 내 변수를 main() 함수 안에 넣었습니다. 프레임 값과 길이를 다른 함수에 매개 변수로 전달하면 문제가 해결됩니다. 다시 한 번 감사드립니다! – KittenMittons

+0

함수 정의를 변경할 필요가없는 대체 방법이 있습니다. ** 글로벌 ** 키워드를 사용하여 범위를 확장 할 수 있습니다. 내 대답을 한번보세요. –

+1

피할 수있을 때마다 전역 변수를 사용하지 말라고 충고합니다. 일반적으로 나쁜 습관으로 간주됩니다. OP의 코드는 실제로 전역 변수가 필요하지 않은 완벽한 예제입니다. 어떤 변수가 어떤 함수를 사용하는지 즉시 볼 수 있기 때문에 매개 변수로 전달하는 것이 좋습니다. –

1

framevalues은 main()의 변수 변수입니다. 인수로 액세스 할 수 있도록 필요한 모든 함수에 framevalues을 전달해야합니다.

변수 유효 범위에서 읽으십시오. 당신이 변수를 할당 할 때 당신은 현재 범위 현재 함수 로컬 즉 에서 그 변수를 작성, Short Description of the Scoping Rules?

1

에서 답을 제시한다.

따라서 framevalues 변수를 으로 지정하면이됩니다. 다음으로 달성 할 수 :

당신은 코드의 나머지 부분을 변경할 필요가 없습니다 이것이 잘 작동합니다

global framevalues 
framevalues = [] 

framevalues = [] 

를 교체합니다.

관련 문제