编写Python方式

时间:2010-05-31 03:47:33

标签: python

我刚刚在Uni学习python的下半学期。我真的很喜欢它,并希望提供一些关于如何编写更多'pythonic'代码的技巧。

这是我最近作业中的__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"

正如你所看到的,它有点笨重。如果有人有时间或倾向,我真的很感激一些关于python最佳实践的技巧。

感谢。

3 个答案:

答案 0 :(得分:5)

可以做一些可以清理代码的事情:

使用字典的setdefault。如果缺少密钥,则将其设置为您提供的默认密钥,然后将其返回。否则,它只是忽略第二个参数并返回字典中的内容。这避免了笨重的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。

答案 1 :(得分:3)

除了orangeoctopus使用setdefault的建议之外,您还可以将if-else重构为调度程序(大型if-else和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)
]

然后做

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

答案 2 :(得分:2)

另一个重要的一点是,如果你想长时间使用脚本(有些人会说很长),就是不要在新代码中使用已弃用的函数:

os.path.walk在python 3.x中消失了。现在您可以使用os.walk代替。但是os.walkos.path.walk不同:它不接受签名中的处理函数。因此,重构代码意味着更改名称。