嗨,我有以下程序
问题: -如何使其美观、可读性更强、简洁。 -如何将公共循环提取到另一个方法。你知道吗
假设:
在给定的rootDir中,dir的组织方式如下所示。你知道吗
过程的作用:
如果输入是200,它将删除所有超过200天的目录。不是基于modifytime,而是基于dir结构和dir名称[我稍后将对每个较旧的dir强制删除“rm-Rf”]
例如dir结构:
-2009(year dirs) [will force delete dirs e.g "rm -Rf" later]
-2010
-01...(month dirs)
-05 ..
-01.. (day dirs)
-many files. [I won't check mtime at file level - takes more time]
-31
-12
-2011
-2012 ...
我拥有的代码:
def get_dirs_to_remove(dir_path, olderThanDays):
today = datetime.datetime.now();
oldestDayToKeep = today + datetime.timedelta(days= -olderThanDays)
oldKeepYear = int(oldestDayToKeep.year)
oldKeepMonth =int(oldestDayToKeep.month);
oldKeepDay = int(oldestDayToKeep.day);
for yearDir in os.listdir(dirRoot):
#iterate year dir
yrPath = os.path.join(dirRoot, yearDir);
if(is_int(yearDir) == False):
problemList.append(yrPath); # can't convery year to an int, store and report later
continue
if(int(yearDir) < oldKeepYear):
print "old Yr dir: " + yrPath
#deleteList.append(yrPath); # to be bruteforce deleted e.g "rm -Rf"
yield yrPath;
continue
elif(int(yearDir) == oldKeepYear):
# iterate month dir
print "process Yr dir: " + yrPath
for monthDir in os.listdir(yrPath):
monthPath = os.path.join(yrPath, monthDir)
if(is_int(monthDir) == False):
problemList.append(monthPath);
continue
if(int(monthDir) < oldKeepMonth):
print "old month dir: " + monthPath
#deleteList.append(monthPath);
yield monthPath;
continue
elif (int(monthDir) == oldKeepMonth):
# iterate Day dir
print "process Month dir: " + monthPath
for dayDir in os.listdir(monthPath):
dayPath = os.path.join(monthPath, dayDir)
if(is_int(dayDir) == False):
problemList.append(dayPath);
continue
if(int(dayDir) < oldKeepDay):
print "old day dir: " + dayPath
#deleteList.append(dayPath);
yield dayPath
continue
print [ x for x in get_dirs_to_remove(dirRoot, olderThanDays)]
print "probList" % problemList # how can I get this list also from the same proc?
这看起来很不错,除了这条评论中提到的一件大事:
听起来像是将
problemList
存储在一个全局变量或其他什么东西中,您想解决这个问题。以下是一些方法:tuple
,其中第一个成员说明它是哪种类型的,第二个成员说明如何处理它。你知道吗problemList
作为参数。请记住list
是可变的,因此附加到参数的内容对调用方是可见的。你知道吗yield
结尾的problemList
,这意味着您需要重新构造使用生成器的方式,因为它不再只是一个简单的迭代器。你知道吗problemList
存储为成员变量。你知道吗problemList
塞进其中,以便调用者可以检索它。你知道吗同时,有几种方法可以使代码更加紧凑和可读。你知道吗
最琐碎的是:
此列表理解与原始迭代完全相同,您可以更简单地编写为:
至于算法本身,您可以对
listdir
进行分区,然后只使用分区的list
即可或者严格地说:
后者可能更有意义,特别是考虑到
yearDirs
已经是一个列表了,而且不太可能有那么大。你知道吗当然,您需要编写
partitionDirs
函数,但好在,您可以在月份和日期级别再次使用它。这很简单。事实上,我实际上可能通过排序来进行分区,因为它使逻辑变得如此明显,即使它更加冗长:如果你环顾四周(也许搜索“python分区排序列表”?),您可以找到很多方法来实现
partitionSortedListAt
函数,但下面是一些我认为对于没有这样考虑问题的人来说很容易理解的东西:如果您搜索“python split predicate”,您还可以找到实现初始剥离的其他方法,尽管请记住,大多数人要么关心能够划分任意iterables(这里不需要),要么关心效率(这里也不关心)。所以,不要寻找别人说的“最好”的答案;看看所有的答案,选一个你觉得最容易理解的。你知道吗
最后,您可能会注意到,您最终得到了三个看起来几乎相同的级别:
您可以通过递归进一步简化这一点,传递到目前为止的路径,以及要检查的进一步级别的列表,您可以将这18行转换为9行。这是否更具可读性取决于您对要传递的信息进行编码的程度以及适当的
yield from
。下面是想法的草图:如果您使用的是一个没有
yield from
的老Python版本,那么早期的东西几乎不需要转换;编写的递归版本将更难看、更痛苦。但在处理递归生成器时,确实无法避免这种情况,因为子生成器不能“通过”调用生成器。你知道吗我建议不要使用发电机,除非你绝对确定你需要它们。在这种情况下,你不需要它们。你知道吗
在下面的例子中,
newer_list
不是严格需要的。虽然categorizeSubdirs
可以进行递归,但我觉得复杂性的增加并不值得重复性的节省(但这只是个人风格的问题;我只在不清楚需要多少级递归或者数字是固定的但很大时才使用递归;在我看来,三级是不够的)。你知道吗最后的三个嵌套循环可以减少重复,但代价是代码复杂度。我认为这不值得,尽管理智的人可能不同意。在其他条件相同的情况下,我更喜欢简单的代码,而不是稍微聪明一点的代码;正如他们所说,读代码比写代码更难,所以如果你写了你能写的最聪明的代码,你就不会足够聪明去读它。:/
相关问题 更多 >
编程相关推荐