2010-05-31 3 views
6

Uni 학습 Python에서 지난 학기를 방금 보냈습니다. 나는 그것을 정말로 즐겼으며 더 많은 'pythonic'코드를 작성하는 방법에 대한 몇 가지 팁을 기대했다.Python 방식 코딩하기

이것은 최근 과제에서 작성한 __init__ 수업입니다. 필자가 쓴 시간에, 나는 람다 (lambdas)를 사용하여, 또는 더 깔끔하고 효율적인 방법으로 이것을 다시 쓸 수있는 방법을 찾지 만, 시간이 없어졌다.

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" 

보시다시피 다소 부피가 커집니다. 누구나 시간이나 성향이 있다면, 파이썬 모범 사례에 대한 몇 가지 팁을 정말 고맙게 생각합니다.

감사합니다. 코드 비트를 정리 할 수 ​​

+0

참고 :이 모듈은'enrol'이라는 모듈의 일부로 클래스 클래스 인 것처럼'__init__' 인'Enroll' 클래스를 포함합니다 –

+3

: http://stackoverflow.com/questions/2943396/python -need-some-help –

+1

이 표정 놀라 울 정도 * http://stackoverflow.com/questions/2943396/python-need-some-help – Johnsyweb

답변

5

커플 일 :

이 사전의을 setDefault를 사용합니다. 키가 누락 된 경우 키를 제공 한 기본값으로 설정 한 다음 키를 반환합니다. 그렇지 않으면 두 번째 매개 변수를 무시하고 사전에 있던 내용을 반환합니다. 이렇게하면 clunky if 문을 피할 수 있습니다.

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]} 

다른 가능성은 os.path.join을 사용하여 파일 경로를 만드는 것입니다. 문자열 연결 만하는 것보다 안전합니다.

os.path.join(dir, file) 

외에도 스타일이 IMO 좋아 보인다.

+0

감사합니다. if/elif를 구현하는 방법은 훨씬 깔끔합니다. –

2

당신이 (일부는 매우 긴 말을) 새 코드에서 사용되지 않는 기능을 사용하지 않는 것입니다 오랫동안 당신이 스크립트를 사용하려면 또 다른 중요한 점 : 파이썬 3.x에서에서 사라진

os.path.walk 이제 대신 os.walk을 사용할 수 있습니다. 그러나 os.walkos.path.walk과 다릅니다. 서명에 처리 기능을 허용하지 않습니다. 따라서 코드를 리팩토링하면 이름을 변경하는 것보다 조금 더 의미가 있습니다. setdefault를 사용하는 orangeoctopus의 제안에 추가

+0

감사합니다. 다른 사람이 다른 포스트에서 내게 그것을 지적했다. 다시 말하지만, 제출하기 전에 그것을 변경할 시간이 없었 습니다만, 지금 살펴 보겠습니다. –

3

, 당신은 리팩토링 할 수있는 경우 - 다른 (IF-다른 및 스위치 큰 문에 대한 일반적인 교체) 디스패처로 :

# 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) 
] 

다음

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

와우, 대단한! 나는 큰 if-else를 찾고 대안을 바꾸었고, 몇 가지를 발견했지만, 아무것도 발견하지 못했습니다. 파이썬은 점점 더 좋아지고 있습니다.) Richard에게 감사드립니다! –

+0

'HandleClasses','HandleSubjects' 등은'filename' 매개 변수가있는 함수입니까? 그리고'dir' var에 접근하기 위해서는 여전히'_read_files' 함수에 정의 된 것들이 필요합니다. –

+1

네, 맞습니다.그 기호가 정의 된 곳에서 정의 된 것이 필요합니다. 'self.HandlerSubjects'로'__init__'에서 할 수 있습니다. –