2014-12-28 37 views
0

如何從callback中找到給函數調用callback函數的參數?(python)從回調中查找父函數的參數

下面的代碼(不完整)將啓動一個調用回調函數的音頻流。它使用pyaudio。

現在,在callback函數中有硬編碼的東西。我試圖擺脫那些。

我讀過pyaudio文檔,我似乎無法將額外的參數傳遞給callback函數。我已經閱讀了inspect python模塊,它的getsourcegetouterframes,這對我來說似乎很有趣,希望能夠得到PlayStream函數的參數,但是這導致我無處可去。

如何從callback內參考SoundGeneratorObject參數?

謝謝。

def PlayStream(SoundGeneratorObject): 
    p = pyaudio.PyAudio() 
    stream = p.open(format = p.get_format_from_width(SoundGeneratorObject.WIDTH), 
       channels = SoundGeneratorObject.CHANNELS, 
       rate = SoundGeneratorObject.BITRATE, 
       frames_per_buffer = SoundGeneratorObject.CHUNKSIZE, 
       output = True, 
       stream_callback = callback) 
    stream.start_stream() 
    while stream.is_active(): 
     time.sleep(0.1) 
    stream.stop_stream() 
    stream.close() 
    p.terminate() 

def callback(in_data, frame_count, time_info, status_flags): 
    signal = waves.next() 
    return (signal, pyaudio.paContinue) 

waves = SoundGenerator() 
PlayStream(waves) 
+0

你有沒有考慮命名'SoundgeneratorObje ct' - >'sound_generator_object'當它是一個參數嗎?我有困惑:) –

+0

哈,好的,會做 - 新手程序員在這裏!感謝您的提示 – grabaldam

+0

只要你保留**而不是來回更改,你可以選擇任何約定:) –

回答

0

你能做這樣的事情來爲你傳遞的回調創建一個範圍嗎?

def callback_maker(waves): 
    def callback(in_data, frame_count, time_info, status_flags): 
     # do stuff (waves is in scope) 
     signal = waves.next() 
     return (signal, pyaudio.paContinue) 
    return callback 

如果可以的話,像這樣使用:

stream = p.open(format = p.get_format_from_width(SoundGeneratorObject.WIDTH), 
       channels = SoundGeneratorObject.CHANNELS, 
       rate = SoundGeneratorObject.BITRATE, 
       frames_per_buffer = SoundGeneratorObject.CHUNKSIZE, 
       output = True, 
       stream_callback = callback_maker(SoundGeneratorObject)) 
+0

工作正常!非常感謝!我是編碼新手,只是開始掌握基本概念,非常感謝您的幫助! – grabaldam

+0

@grabaldam沒問題,只要確保你知道爲什麼它的工作:) –

+1

是的,我明白邏輯!謝謝! – grabaldam

1

雖然答案已被接受,我想表現出一種替代,如何在技術上則可以通過從父函數訪問參數使用檢查全局(),此示例將工作:

import inspect 

# as argument 
SoundGeneratorObject = 'Hello World' 

def PlayStream(SoundGeneratorObject): 
    a, b, c = 8, 9, 10 
    print "do a callback" 
    callback(a, b, c) 

def callback(a, b, c): 
    print a, b, c 
    # inspect.stack[1][3] can get the function name that called the callback 
    # inner globals then access to the function by its name 
    # func_code.co_varnames will then get the argument name from the function 
    # since you only have 1 argument, that's why I use index [0] 
    # the outer globals will then access the argument value by its name 
    print globals()[globals()[inspect.stack()[1][3]].func_code.co_varnames[0]] 

# call the parent function 
PlayStream(SoundGeneratorObject) 

do a callback 
8 9 10 
Hello World # successfully get the argument value