以Python的方式编程
我刚刚在大学里学习了半个学期的Python,感觉非常不错。现在我希望能得到一些建议,教我怎么写得更“Pythonic”,也就是更符合Python风格的代码。
这是我最近一个作业里的__init__
类。当时我在写的时候,想着怎么用lambda表达式或者更整洁、更高效的方式来重写它,但时间不够了。
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 个回答
2
如果你想让你的脚本长时间使用(有些人会说是非常长的时间),还有一个重要的点就是不要在新代码中使用已经不推荐使用的函数:
os.path.walk
在 Python 3.x 中已经不再使用了。现在你可以用 os.walk
来代替。不过 os.walk
和 os.path.walk
是不一样的:它的参数中不接受处理函数。所以,修改你的代码不仅仅是换个名字这么简单,还需要做一些额外的调整。
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
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)
除此之外,我觉得在风格上看起来不错。