2017-10-03 1 views
0

Tout en travaillant avec un code que mon professeur m'a donné pour utiliser dans une affectation, je ne peux pas changer selon les instructions. J'ai regardé autour et ajouté la fermeture autour de l'écriture initiale mais est là pour empêcher de modifier le code de démarrage?AttributeError: l'instance Wave_write n'a pas d'attribut '__exit__'

Le code est provenu

Appel de code:

def run_menu(): 

    global CURRENT_TIME 

    # Provide a minimal indication that the program has started. 
    print(MINIMAL_HELP_STRING) 

    # Get the first keystroke. 
    c = readchar.readchar() 

    # Endless loop responding to the user's last keystroke. 
    # The loop breaks when the user hits the QUIT_MENU_KEY. 
    while True: 

     # Respond to the user's input. 
     if c == FORWARD_KEY: 

      # Advance the time, looping back around to the start. 
      CURRENT_TIME += 1 
      if CURRENT_TIME == len(NUMBERS_WAV): 
       CURRENT_TIME = 0 

      # Concatenate three audio files to generate the message. 
      sound.combine_wav_files(TMP_FILE_WAV, YOU_SELECTED_WAV, 
            NUMBERS_WAV[CURRENT_TIME], AM_WAV) 

      # Play the concatenated file. 
      sound.Play(TMP_FILE_WAV) 

Code de fonction:

def combine_wav_files(out_file, *files): 
    with wave.open(out_file, 'wb') as out: 
     with wave.open(files[0], 'rb') as first_in: 
      (nchannels, sampwidth, framerate, nframes, comptype, compname) =\ 
       first_in.getparams() 
      out.setparams(first_in.getparams()) 
     for filename in files: 
      with wave.open(filename, 'rb') as cur_in: 
       if (cur_in.getnchannels() != nchannels or 
        cur_in.getsampwidth() != sampwidth or 
        cur_in.getframerate() != framerate or 
        cur_in.getcomptype() != comptype or 
        cur_in.getcompname() != compname): 
        raise Exception('Mismatched file parameters: ' + filename) 
       out.writeframes(cur_in.readframes(cur_in.getnframes())) 

Message d'erreur:

Exception wave.Error: Error('# channels not specified',) in <bound method Wave_write.__del__ of <wave.Wave_write instance at 0x104029e60>> ignored 
Traceback (most recent call last): 
    File "sample_menu.py", line 144, in <module> 
     main() 
    File "sample_menu.py", line 25, in main 
     run_menu() 
    File "sample_menu.py", line 113, in run_menu 
     NUMBERS_WAV[CURRENT_TIME], AM_WAV) 
    File "/Users/jaredsmith/Desktop/443/P1 Starter Code 2017/sound.py", line 86, in combine_wav_files 
     with wave.open(out_file, 'wb') as out: 
AttributeError: Wave_write instance has no attribute '__exit__' 

je mets le correctif dans les importations et il fonctionne!

Fix (mise à jour):

#### 
# From http://web.mit.edu/jgross/Public/21M.065/sound.py 9-24-2017  
#### 

def _trivial__enter__(self): 
    return self 
def _self_close__exit__(self, exc_type, exc_value, traceback): 
    self.close() 

wave.Wave_read.__exit__ = wave.Wave_write.__exit__ = _self_close__exit__ 
wave.Wave_read.__enter__ = wave.Wave_write.__enter__ = _trivial__enter__ 

Répondre

0

Vous utilisez une instance Wave_write dans une instruction with. Pour fonctionner correctement, Wave_write doit être un gestionnaire de contexte, ce qui signifie qu'il doit implémenter les deux méthodes __enter__() et __exit__(). Ce n'est pas le cas ici.

Vous devez ajouter la méthode __exit__ à Wave_write, ou supprimer l'instruction with et fermer l'entrée manuellement (si nécessaire). Exemple:

out = wave.open(out_file, 'wb'): 
    [do_stuff] 
out.close() # if Wave_write implements a closing method, use it. the with statement and __exit__() method would have handled that for you. 

Voir https://docs.python.org/2/reference/compound_stmts.html#with et https://docs.python.org/2/library/contextlib.html

+0

Merci! M'a aidé à comprendre comment le réparer –

0

Le with mot-clé dans cette ligne

with wave.open(out_file, 'wb') as out 

implique que wave.open a été écrit en tant que gestionnaire de contexte, mais il n'a pas. Sortez le with et le faire à la place:

out = wave.open(out_file, 'wb') 
0

Si ce code vous a été donné par votre professeur alors qu'il utilisait python3, où l'objet retourné par wave.open() peut être utilisé en tant que gestionnaire de contexte. Vous semblez utiliser python2, ce qui n'était pas le cas.

Vous devriez utiliser la même version que votre professeur, sinon vous rencontrerez de tels problèmes tout le temps. Donc, vous devriez probablement passer à python3.