2015-04-30 21 views
5

Tôi có một số mã để đổi tên toàn bộ các tệp và di chuyển chúng sang thư mục mới bằng cách sử dụng os.rename(). Nó khá đơn giản, không có gì hào nhoáng. Nó hoạt động cho đến khi tôi có một số chồng lên nhau theo lô và có các tệp trùng lặp, điều này đã tăng lên một số WindowsError. Kể từ khi các mã làm việc trong tất cả các otherways, tôi đã làmGhi ngoại lệ cụ thể bằng cách thử ... ngoại trừ

try: 
    os.rename(...) 
except WindowsError: 
    print "Duplicate file {}".format(fileName) 

này làm việc tốt, ngoại trừ việc nó ngụ ý rằng tất cả WindowsError s là từ các tập tin trùng lặp. Kết quả là khi một khía cạnh khác của kịch bản của tôi bị phá vỡ, nó không thành công về cơ bản âm thầm.

Làm cách nào tôi có thể sử dụng try...except để chỉ bắt ngoại lệ cụ thể? Nếu nó không thể, những cách giải quyết tồn tại?

+0

bạn có thể thử 'bắt WindowsError như e: 'và nhìn vào' str (e)', và 'dir (e)' –

+0

@JoranBeasley, tôi nghĩ về điều đó, nhưng không phải là chuỗi kết hợp với hệ thống ngoại lệ phụ thuộc? – wnnmaw

+0

ý của bạn là gì? –

Trả lời

5

Theo documentation:

"Giá trị errno bản đồ giá trị winerror tương ứng errno.h giá trị."

Vì lý do này, bạn sẽ có thể phân biệt giữa các lỗi Windows khác nhau bằng cách sử dụng errno.

Ví dụ:

try: 
    fp = open("nother") 
except IOError as e: 
    print e.errno 
    print e 
1

tôi đã viết một người quản lý bối cảnh để ngăn chặn OSError dựa trên giá trị errno. Dưới đây là trình quản lý ngữ cảnh, chỉ cần viết lại một chút để bắt WinError thay thế.

Mã ví dụ của bạn in một thông báo khi lỗi xảy ra, nhưng điều này sẽ không in bất cứ điều gì; nó âm thầm ngăn chặn ngoại lệ.

Tôi chưa thử nghiệm điều này vì tôi không có Windows tiện dụng, nhưng tôi đã thử nghiệm bản gốc và đây là một chỉnh sửa tầm thường. Hãy cho tôi biết nếu bạn có bất kỳ rắc rối với điều này.

Chức năng phương thức .__exit__() nhận thông tin về bất kỳ trường hợp ngoại lệ nào nhận được và nếu trả về True ngoại lệ sẽ bị loại bỏ; nếu nó trả về False ngoại lệ được nêu ra như bình thường. Do đó, điều này chỉ loại trừ ngoại lệ nếu loại phù hợp (đó là một ngoại lệ WinError) và thuộc tính .errno khớp với giá trị được lưu self.errno.

class suppress_winerror(object): 
    def __init__(self, errno): 
     self.errno = errno 

    def __enter__(self): 
     return self 

    def __exit__(self, e_type, e_val, e_tb): 
     if e_type is not WinError: 
      return False 
     if e_val.errno != self.errno: 
      return False 
     return True 

Ví dụ về cách sử dụng. Tôi giả định rằng mã lỗi cửa sổ đang được ánh xạ lên errno.EEXIST, mã errno cho "tệp đã tồn tại". Rõ ràng nếu tôi đã sai, bạn nên đặt đúng mã lỗi thay thế.

import errno 

with suppress_winerror(errno.EEXIST): 
    os.rename(old_fname, new_fname) 
Các vấn đề liên quan