我刚刚在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最佳实践的技巧。
感谢。
答案 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.walk
与os.path.walk
不同:它不接受签名中的处理函数。因此,重构代码意味着更改名称。