2016-10-03 32 views
0

所以,我有兩個文件,所以要檢查它的有效性,我執行tryexcept兩次。但我不認爲這是一個好方法,你能提出一個更好的方法嗎?如何執行兩個文件的錯誤處理?

這裏是我的代碼:

def form_density_dictionary(self,word_file,fp_exclude): 
    self.freq_dictionary={} 
    try: 
     with open(fp_exclude,'r')as fp2: 
      words_excluded=fp2.read().split() #words to be excluded stored in a list 
      print("**Read file successfully :" + fp_exclude + "**") 
      words_excluded=[words.lower() for words in words_excluded] # converted to lowercase 

    except IOError: 
     print("**Could not read file:", fp_exclude, " :Please check file name**") 
     sys.exit() 

    try: 
     with open(word_file,'r') as file: 
      print("**Read file successfully :" + word_file + "**") 
      words_list=file.read() 
      if not words_list: 
       print("**No data in file:",word_file +":**") 
       sys.exit() 
      words_list=words_list.split() 
      words_list=[words.lower() for words in words_list] # lowercasing entire list 
     unique_words=list((set(words_list)-set(words_excluded))) 

     self.freq_dictionary= {word:("%6.2f"%(float((words_list.count(word))/len(words_list))*100)) for word in unique_words} 
     #print((len(self.freq_dictionary))) 
    except IOError: 
     print("**Could not read file:", word_file, " :Please check file name**") 
     sys.exit() 

任何其他建議也歡迎,使之更加符合Python。

+0

還有兩個想法,使你的代碼更「Python化」:第一,使用'格式'而不是字符串concat'「**成功讀取文件:」+ fp_exclude +「**」 - >'「**成功讀取文件:{」**「.format(fp_exclude)'。其次,使用內置函數,如'map':'words_list = [words.lower()for words_list]' - >'list(map(str.lower,words))' –

+0

是啊,謝謝mate :) –

回答

1

即跳出是缺乏連貫性和可讀性的第一件事就是:在你與縮進一些行4個空間,其他人只使用兩個;在某些地方,你在逗號後面加空格,在其他地方你沒有,在大多數地方,你的空間周圍沒有空間(=)...

保持一致並使代碼可讀。最常用的格式是使用四個空格進行縮進,並且在逗號後總是有一個空格,但比這更重要的是要保持一致,這意味着無論您選擇什麼,都要堅持使用整個代碼。它使得包括你自己在內的每個人都可以更輕鬆地閱讀。

這裏有一些其他的事情我想你可以改善:

  • 有一個異常處理塊,而不是兩個。

  • 您也可以在單行打開這兩個文件。

  • 更妙的是,結合了以前的建議,並有一個單獨的方法來讀取文件中的數據,從而消除重複代碼,使主要方法更易於閱讀。

  • 對於字符串格式化,最好使用.format()而不是%。看看這個:https://pyformat.info/

  • 總的來說,儘量避免在你的代碼中重複。如果有一些事情你不止一次地完成,將它解壓到一個單獨的函數或方法中,然後使用它。

這裏是你的代碼快速修改如何,我大概會寫,並考慮這些事情考慮:

import sys 


class AtifImam: 
    def __init__(self): 
     self.freq_dictionary = {} 

    def form_density_dictionary(self, word_file, exclude_file): 
     words_excluded = self.read_words_list(exclude_file) 
     words_excluded = self.lowercase(words_excluded) 

     words_list = self.read_words_list(word_file) 
     if len(words_list) == 0: 
      print("** No data in file: {} **".format(word_file)) 
      sys.exit() 

     words_list = self.lowercase(words_list) 

     unique_words = list((set(words_list) - set(words_excluded))) 

     self.freq_dictionary = { 
      word: ("{:6.2f}".format(
       float((words_list.count(word))/len(words_list)) * 100)) 
      for word in unique_words 
      } 

    @staticmethod 
    def read_words_list(file_name): 
     try: 
      with open(file_name, 'r') as file: 
       data = file.read() 
       print("** Read file successfully: {} **".format(file_name)) 
       return data.split() 
     except IOError as e: 
      print("** Could not read file: {0.filename} **".format(e)) 
      sys.exit() 

    @staticmethod 
    def lowercase(word_list): 
     return [word.lower() for word in word_list] 
+0

是的,這會好得多。謝謝^ _^ –

+0

但是,如果你會看到我的代碼,我打開兩個文件,那麼如何在同一個try中處理兩個文件? –

+0

我也打開這兩個文件。有兩個對'read_words_list'方法的調用,一個用於'words_excluded',另一個用於'words_list'。 – borfast

1

拋出異常,涉及文件系統路徑有一個filename屬性,可以代替你做使用顯式屬性word_filefp_exclude

這意味着您可以將這些IO操作包裝在同一個try-except中,並使用exception_instance.filename這將指示無法執行操作的文件。

例如:

try: 
    with open('unknown_file1.py') as f1, open('known_file.py') as f2: 
     f1.read() 
     f2.read() 
except IOError as e: 
    print("No such file: {0.filename}".format(e)) 

最終打印出:

No such file: unknown_file1.py 

雖然相反:

try: 
    with open('known_file.py') as f1, open('unknown_file2.py') as f2: 
     f1.read() 
     f2.read() 
except IOError as e: 
    print("No such file: {0.filename}".format(e)) 

打印出:

No such file: unknown_file2.py 
+0

有什麼辦法讓用戶知道哪些文件不存在?根據你的回答,錯誤陳述根據我們打開文件的順序打印? –

+0

當發現異常時,打印出文件名。第一個引發'IOError'的文件將是用戶通知的文件。既然'sys.exit'在發生'IOError'的情況下,我提供的功能與您的功能相似,只是包裝了一下。 –

+0

OKay,非常感謝:) –

1

爲了更加「pythonic」,你可以使用什麼是callec Counter,從集合庫。

from collections import Counter 


def form_density_dictionary(self, word_file, fp_exclude): 
    success_msg = '*Read file succesfully : {filename}' 
    fail_msg = '**Could not read file: {filename}: Please check filename' 
    empty_file_msg = '*No data in file :{filename}:**' 
    exclude_read = self._file_open(fp_exclude, success_msg, fail_msg, '') 
    exclude = Counter([word.lower() for word in exclude_read.split()]) 
    word_file_read = self._file_open(word_file, success_msg, fail_msg, empty_file_msg) 
    words = Counter([word.lower() for word in word_file_read.split()]) 
    unique_words = words - excluded 
    self.freq_dictionary = {word: '{.2f}'.format(count/len(unique_words)) 
          for word, count in unique_words.items()} 

此外,它會更好,如果你只是創建OPEN_FILE方法,如:

def _open_file(self, filename, success_msg, fails_msg, empty_file_msg): 
    try: 
     with open(filename, 'r') as file: 
      if success_msg: 
       print(success_msg.format(filename= filename)) 
      data = file.read() 
      if empty_file_msg: 
       print(empty_file_msg.format(filename= filename)) 
      return data 
    except IOError: 
      if fail_msg: 
       print(fail_msg.format(filename= filename)) 
      sys.exit() 
+0

非常感謝你^ _^ –

+0

我改變了一種結構(添加一個,額外的方法來處理文件打開) – Nf4r

+0

是的,這看起來好多了。謝謝 –