2010-05-31 35 views
6

Tôi vừa dành nửa học kỳ cuối cùng tại Uni learning python. Tôi đã thực sự rất thích nó, và đã hy vọng cho một vài lời khuyên về cách viết thêm mã 'pythonic'.Mã hóa cách Python

Đây là lớp học __init__ từ bài tập gần đây tôi đã làm. Vào thời điểm tôi đã viết nó, tôi đã cố gắng tìm ra cách tôi có thể viết lại nó bằng cách sử dụng lambdas, hoặc trong một cái neater, cách hiệu quả hơn, nhưng hết thời gian.

def __init__(self, dir): 

    def _read_files(_, dir, files): 

     for file in files: 

      if file == "classes.txt": 
       class_list = readtable(dir+"/"+file) 
       for item in class_list: 
        Enrol.class_info_dict[item[0]] = item[1:] 
        if item[1] in Enrol.classes_dict: 
         Enrol.classes_dict[item[1]].append(item[0]) 
        else: 
         Enrol.classes_dict[item[1]] = [item[0]] 

      elif file == "subjects.txt": 
       subject_list = readtable(dir+"/"+file) 
       for item in subject_list: 
        Enrol.subjects_dict[item[0]] = item[1] 

      elif file == "venues.txt": 
       venue_list = readtable(dir+"/"+file) 
       for item in venue_list: 
        Enrol.venues_dict[item[0]] = item[1:] 

      elif file.endswith('.roll'): 
       roll_list = readlines(dir+"/"+file) 
       file = os.path.splitext(file)[0] 
       Enrol.class_roll_dict[file] = roll_list 
       for item in roll_list: 
        if item in Enrol.enrolled_dict: 
         Enrol.enrolled_dict[item].append(file) 
        else: 
         Enrol.enrolled_dict[item] = [file] 


    try: 
     os.path.walk(dir, _read_files, None) 
    except: 
     print "There was a problem reading the directory" 

Như bạn có thể thấy, nó hơi cồng kềnh. Nếu bất cứ ai có thời gian hoặc độ nghiêng, tôi thực sự đánh giá cao một vài lời khuyên về một số thực hành tốt nhất python.

Cảm ơn.

+0

Lưu ý: đây là một phần của mô-đun được gọi là 'enrol', chứa lớp' Enrol' mà đây là '__init__' –

+3

trông giống như bạn có một người bạn cùng lớp: http://stackoverflow.com/questions/2943396/python -need-some-help –

+1

Giao diện này s * đáng kể * như http://stackoverflow.com/questions/2943396/python-need-some-help – Johnsyweb

Trả lời

5

Vài thứ có thể làm sạch mã của bạn một chút:

Sử dụng bộ nhớ của từ điển. Nếu khóa bị thiếu, sau đó nó sẽ đặt nó thành mặc định mà bạn cung cấp, sau đó trả về. Nếu không, nó chỉ bỏ qua tham số thứ 2 và trả về những gì có trong từ điển. Điều này tránh các câu lệnh if clunky.

Enrol.venues_dict.setdefault(key, []).append(file) 

>>> x = {} 
>>> x.setdefault(99, []).append(5) 
>>> x.setdefault(99, []).append(6) 
>>> x 
{99: [5, 6]} 
>>> x.setdefault(100, []).append(1) 
>>> x 
{99: [5, 6], 100: [1]} 

Khả năng khác là sử dụng os.path.join để tạo đường dẫn tệp. Điều này là an toàn hơn là chỉ làm chuỗi nối.

os.path.join(dir, file) 

Khác hơn thế, có vẻ tốt về phong cách, IMO.

+0

Cảm ơn, đó là một cách thực hiện nhiều hơn nếu/elif. –

2

Một điểm quan trọng nếu bạn muốn sử dụng bạn kịch bản trong thời gian dài (một số sẽ nói rất dài) là không sử dụng các chức năng bị phản đối trong mã mới:

os.path.walk biến mất trong python 3.x. Bây giờ bạn có thể sử dụng os.walk để thay thế. Tuy nhiên os.walk khác với os.path.walk: nó không chấp nhận chức năng xử lý trong chữ ký của nó. Vì vậy, việc tái cấu trúc mã của bạn sẽ hàm ý nhiều hơn một chút so với việc đổi tên.

+0

cảm ơn joaquin. Một người khác đã chỉ ra điều đó cho tôi trong một bài đăng khác. Một lần nữa, tôi không có thời gian để thay đổi nó trước khi gửi nó, nhưng tôi, tôi sẽ có một cái nhìn lúc đó. –

3

Ngoài gợi ý orangeoctopus để sử dụng setdefault, bạn có thể cấu trúc lại các if-else thành một điều phối (thay thế điển hình cho báo cáo lớn if-else và switch):

# list of 2-tuples: (bool func(string filename), handler_function) 
handlers = [ 
    ((lambda fn: fn == "classes.txt"), HandleClasses), 
    ((lambda fn: fn == "subjects.txt"), HandleSubjects), 
    ((lambda fn: fn.endswith(".roll")), HandleRoll) 
] 

sau đó làm

for filename in files: 
    for matcher, handler in handlers: 
    if matcher(filename): 
     handler(filename) 
     break 
+1

Thật tuyệt vời! Tôi đang tìm kiếm một công ty lớn và thay thế, và tìm thấy một số ít, nhưng không có gì sạch sẽ. Python chỉ tiếp tục ngày càng tốt hơn;) Cảm ơn Richard! –

+0

chỉ để làm rõ, 'HandleClasses',' HandleSubjects' vv là các hàm có tham số 'filename'? Và tôi vẫn cần chúng được định nghĩa trong hàm '_read_files' để truy cập vào' dir' var? –

+1

Có, đúng.Bạn sẽ cần chúng xác định một nơi nào đó mà những biểu tượng được xác định. Bạn cũng có thể làm điều đó trong '__init__' như' self.HandlerSubjects'. –