Python组织文件 实践:查找大文件、 用Mb、kb显示文件尺寸 、计算程序运行时间
这个小程序很简单原本没有记录下来的必要,但在编写过程中又让我学到了一些新的知识,并且遇到了一些不能解决的问题,然后,然后就很有必要记录一下。
这个程序的关键是获取文件大小,本来用 os.path.getsize(path) 就能解决,但是我还想让他用MB、kb这样的单位来显示,并且能显示运行时间,这就又接触到了新知识,最后在在应用计时模块timeit时遇到了一个问题,花了很长时间也没有解决
完整代码如下:
#! python3
#chapter09-test02.py - 找出一个文件夹内的大文件,并打印出大文件的绝对路径
#-----为了防止运行时间过长,我把程序设置为了只检查前1000个超过size的文件,他们并不是最大的1000个 import os,pprint,sys
import timeit,time #装饰器--计算程序运行时间
def colocked_decorator(func):
def colock(*args):
startTime=timeit.default_timer()
result=func(*args) #运行程序
spendTime=timeit.default_timer()-startTime
name=func.__name__ #获取程序名字
arg_str=','.join(repr(arg) for arg in args) #注意不是*args 组成程序参数的字符串
print('[0.7fs] %s(%s) '%(spendTime,name,arg_str),end='')
print('%r',result)
return result
return colock #寻找指定文件夹内的的大文件
#返回包含所有大文件的绝对地址的一个列表
#folder-指定的文件夹地址
#size-阈值,超过这个为大文件
@colocked_decorator
def findBigFile(folder,size):
bigFileAbs=[]
for foldername,subfolders,filenames in os.walk(folder):
#对文件进行遍历
for filename in filenames:
#.getsize(path)必须是完整路径
fileAbs=os.path.join(foldername,filename)
if os.path.getsize(fileAbs)>size and len(bigFileAbs)<100:
#fileAbs=os.path.join(foldername,filename)
fileAbs=os.path.abspath(fileAbs)
bigFileAbs.append(fileAbs)
return bigFileAbs #定义一个函数用来将尺寸变为KB、MB这样的单位,但是没有在这个程序中使用
#size-是os.getsize()返回的文件尺寸数值
#is_1024_byte 代表以1024去转化还是1000去转化,默认是1024
#先定义的后缀
SUFFIXES = {1000:['KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'],
1024:['KiB', 'MiB', 'GiB', 'TiB', 'PiB', 'EiB', 'ZiB', 'YiB']}
def humanReadable_size(size,is_1024_byte=True):
#mutiple默认是1000
mutiple=1000 if is_1024_byte else 1024
#与for遍历结合起来,这样来进行递级的转换
for suffix in SUFFIXES[mutiple]:
size/=mutiple
#直到Size小于能往下一个单位变的数值
if size<mutiple:
return '{0:.1f}{1}'.format(size,suffix)
raise ValueError('number too large') path='F:\DCIM'
size=1000000 #设定的阈值
#先判断路径是否存在
if os.path.exists(path):
resultList=findBigFile(path,size)
pprint.pprint(resultList) else:
print('You enter path does not exist')
sys.exit()
转换大小单位
从网上到的程序是这样的 来源
但是我看不懂,经过研究,把理解的部分注释上去了
#定义一个函数用来将尺寸变为KB、MB这样的单位
#size-是os.getsize()返回的文件尺寸数值
#is_1024_byte 代表以1024去转化还是1000去转化,默认是1024
#先定义的后缀
SUFFIXES = {1000:['KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'],
1024:['KiB', 'MiB', 'GiB', 'TiB', 'PiB', 'EiB', 'ZiB', 'YiB']}
def humanReadable_size(size,is_1024_byte=True):
#mutiple默认是1000
mutiple=1000 if is_1024_byte else 1024
#与for遍历结合起来,这样来进行递级的转换
for suffix in SUFFIXES[mutiple]:
size/=mutiple
#直到Size小于能往下一个单位变的数值
if size<mutiple:
return '{0:.1f}{1}'.format(size,suffix)
raise ValueError('number too large') #抛出异常
计算程序运行时间
补充
这是隔了一段时间又看到的一个计时的方法,之前一直用time.time来计时,最近看到了一篇介绍timeit的文章,竟然也很方便,记录的时候惊讶的发现原来竟然也用过timeit,只是遇到了很多问题,果然好记性不如烂笔头啊
参考链接:https://www.cnblogs.com/PrettyTom/p/6657984.html
timeit是python提供的强大的计时库,不仅使用方便,而且还可以让函数重复运行
测试语句执行时间:
#看x=1的执行时间,执行1次(number可以省略,默认值为1000000):
timeit('x=1', number=1) #看一个列表生成器的执行时间,执行1次:
timeit('[i for i in range(10000)]', number=1)
测试函数运行时间:
# timeit(函数名_字符串,运行环境_字符串,number=运行次数)
t = timeit('func()', 'from __main__ import func', number=1000)
print(t)
另外一个重复运行repeat
由于电脑永远都有其他程序也在占用着资源,你的程序不可能最高效的执行。所以一般都会进行多次试验,取最少的执行时间为真正的执行时间。
from timeit import repeat def func():
s = 0
for i in range(1000):
s += i #repeat和timeit用法相似,多了一个repeat参数,表示重复测试的次数(可以不写,默认值为3.),返回值为一个时间的列表。
t = repeat('func()', 'from __main__ import func', number=100, repeat=5)
print(t)
print(min(t))
另外,我又学习了计时器的部分信息为程序增加了一个计算查询耗时的功能
work_time=repeat(findBigFile(path,1000000),
'from _main_ import findBigFile',number=1,repeat=1) #repeat=1代表运行一轮,number=1代表每轮运行一次,返回一个每次运行时间的列表
但加上之后就出现了错误
Traceback (most recent call last):
File "C:/Users/Administrator.SC-132/AppData/Local/Programs/Python/Python37/chapter09-test02-判断文件大小.py", line 45, in <module>
'from _main_ import findBigFile',number=1,repeat=1)
File "C:\Users\Administrator.SC-201605202132\AppData\Local\Programs\Python\Python37\lib\timeit.py", line 237, in repeat
return Timer(stmt, setup, timer, globals).repeat(repeat, number)
File "C:\Users\Administrator.SC-201605202132\AppData\Local\Programs\Python\Python37\lib\timeit.py", line 128, in __init__
raise ValueError("stmt is neither a string nor callable")
ValueError: stmt is neither a string nor callable
搞了半天无果后发现 stmt是个变量,以为找到了题眼,三秒钟后发出一声叹气后继续思考,考虑是否是findBigFile有返回值的原因,遂测试,然而无果
突然发现是语法的问题,要写成这样才行。
from timeit import timeit def foo():
x=1
work_time=timeit('foo()','from __main__ import foo',number=10)#这里要加引号
print(work_time)
这样可以解决上面的错误,能运行了,然后我又测试有参数的函数如下
from timeit import timeit def foo(argv1,argv2): #这次有参数
argv1+=argv2
#return argv1 num1=1
num2=1
work_time=timeit('foo(num1,num2)','from __main__ import foo',number=10)#这里要加括号
print(work_time)
又出现了错误
Traceback (most recent call last):
File "C:\Users\Administrator.SC-201605202132\AppData\Local\Programs\Python\Python37\forTest.py", line 10, in <module>
'from __main__ import foo',number=10)#这里要加括号
File "C:\Users\Administrator.SC-201605202132\AppData\Local\Programs\Python\Python37\lib\timeit.py", line 232, in timeit
return Timer(stmt, setup, timer, globals).timeit(number)
File "C:\Users\Administrator.SC-201605202132\AppData\Local\Programs\Python\Python37\lib\timeit.py", line 176, in timeit
timing = self.inner(it, self.timer)
File "<timeit-src>", line 6, in inner
NameError: name 'num1' is not defined
我突发奇想把timeit()函数改成了这样:
work_time=timeit('foo(1,1)','from __main__ import foo',number=10)#直接把值传进去,不用变量
将程序中的代码改成上面调用方式,经过测试可以运行,只是需要注意假如参数时字符串时,需要注意参数的引号不能与这个函数外部的引号匹配上即:
work_time=timeit('findBigFile("F:\DCIM",1000000)', #这里要使用双引号
'from __main__ import findBigFile',number=1)
这样就好了,然后我想到“没有定义的变量”这个错误是不是由于from __main__ import foo这里没有为foo指定参数然后我又这样试了一下:
work_time=timeit('foo(1,1)','from __main__ import foo(num1,num2)',number=10)
然而无效:
Traceback (most recent call last):
File "C:\Users\Administrator.SC-201605202132\AppData\Local\Programs\Python\Python37\forTest.py", line 9, in <module>
work_time=timeit('foo(1,1)','from __main__ import foo(num1,num2)',number=10)#这里要加括号
File "C:\Users\Administrator.SC-201605202132\AppData\Local\Programs\Python\Python37\lib\timeit.py", line 232, in timeit
return Timer(stmt, setup, timer, globals).timeit(number)
File "C:\Users\Administrator.SC-201605202132\AppData\Local\Programs\Python\Python37\lib\timeit.py", line 109, in __init__
compile(setup, dummy_src_name, "exec")
File "<timeit-src>", line 1
from __main__ import foo(num1,num2)
^
SyntaxError: invalid syntax
我开始去找return Timer(stmt, setup, timer, globals).timeit(number)这里面每个参数的意思,找到了这个:
1) timeit.timeit(stmt='pass', setup='pass', timer=<defaulttimer>, number=1000000) 返回:返回执行stmt这段代码number遍所用的时间,单位为秒,float型
参数:stmt:要执行的那段代码
setup:执行代码的准备工作,初始化代码或构建环境导入语句,不计入时间,一般是import之类的
timer:这个在win32下是time.clock(),linux下是time.time(),默认的,不用管
number:要执行stmt多少遍
我觉得这个setup可能有用然后修改代码:
num4=1
num3=1
work_time=timeit('foo(num1,num2)','num3,num4','from __main__ import foo',number=10)#这里要加括号
print(work_time)
出现错误
Traceback (most recent call last):
File "C:\Users\Administrator.SC-201605202132\AppData\Local\Programs\Python\Python37\forTest.py", line 9, in <module>
work_time=timeit('foo(num1,num2)','num3,num4','from __main__ import foo',number=10)#这里要加括号
File "C:\Users\Administrator.SC-201605202132\AppData\Local\Programs\Python\Python37\lib\timeit.py", line 232, in timeit
return Timer(stmt, setup, timer, globals).timeit(number)
File "C:\Users\Administrator.SC-201605202132\AppData\Local\Programs\Python\Python37\lib\timeit.py", line 176, in timeit
timing = self.inner(it, self.timer)
File "<timeit-src>", line 3, in inner
NameError: name 'num3' is not defined
我有想到是不是可以像from __main__ import foo一样去导入变量,
work_time=timeit('foo(num1,num2)','from __main__ import num1',
'from __main__ import num2'
,'from __main__ import foo',number=10)#这里要加括号
又被摩擦了一次
Traceback (most recent call last):
File "C:\Users\Administrator.SC-201605202132\AppData\Local\Programs\Python\Python37\forTest.py", line 11, in <module>
,'from __main__ import foo',number=10)#这里要加括号
TypeError: timeit() got multiple values for argument 'number'
然后放弃,哈哈,感觉一下子解脱了呢
换个思路解决问题,
使用修饰器来为这个带参数的函数测试时间
#装饰器--计算程序运行时间
def colocked_decorator(func):
def colock(*args):
startTime=timeit.default_timer()
result=func(*args) #运行程序
spendTime=timeit.default_timer()-startTime
name=func.__name__ #获取程序名字
arg_str=','.join(repr(arg) for arg in args) #注意不是*args 组成程序参数的字符串
print('[%0.7fs] %s(%s) '%(spendTime,name,arg_str),end='')
print('%r',result)
return result
return colock
遇到的问题:
1)
Traceback (most recent call last):
File "C:/Users/Administrator.SC-201605202132/AppData/Local/Programs/Python/Python37/chapter09-test02-判断文件大小.py", line 59, in <module>
resultList=findBigFile(path,size)
TypeError: 'NoneType' object is not callable
我首先去测试函数不修饰时有没有问题,经过测试没有,加上修饰器后才有问题,我就去检查修饰器,发现了修饰器没有写return 修复过后
2) “并非在字符格式化期间转换所有参数”--字符格式化符号没写对
Traceback (most recent call last):
File "C:/Users/Administrator.SC-201605202132/AppData/Local/Programs/Python/Python37/chapter09-test02-判断文件大小.py", line 61, in <module>
resultList=findBigFile(path,size)
File "C:/Users/Administrator.SC-201605202132/AppData/Local/Programs/Python/Python37/chapter09-test02-判断文件大小.py", line 16, in colock
print('[0.7fs] %s(%s) '%(spendTime,name,arg_str),end='')
TypeError: not all arguments converted during string formatting
经过检查是这里的问题
print('[0.7fs] %s(%s) '%(spendTime,name,arg_str),end='')
应该为
print('[%0.7fs] %s(%s) '%(spendTime,name,arg_str),end='')
好了
Python组织文件 实践:查找大文件、 用Mb、kb显示文件尺寸 、计算程序运行时间的更多相关文章
- Linux如何查找大文件或目录总结
在Windows系统中,我们可以使用TreeSize工具查找一些大文件或文件夹,非常的方便高效,在Linux系统中,如何去搜索一些比较大的文件呢?下面我整理了一下在Linux系统中如何查找大文件或文件 ...
- 在linux/unix中查找大文件
在linux/unix中查找大文件,如查找大于100M文件的位置路径,查找等于10M文件的位置路径等等,下面就介绍几个实现快速查找的命令: 1. 查找指定目录下所有大于100M的文件,命令为 find ...
- CentOS下如何查找大文件
在Windows系统中,我们可以使用TreeSize工具查找一些大文件或文件夹,非常的方便高效,在Linux系统中,如何去搜索一些比较大的文件呢?下面我整理了一下在Linux系统中如何查找大文件或文件 ...
- centos磁盘爆满,查找大文件并清理
今天发现vps敲入crontab -e 居然提示 “Disk quota exceeded” 无法编辑.于是"df -h"查了查发现系统磁盘空间使用100%了.最后定位到是/var ...
- Linux如何查找大文件或目录总结-1127
原帖地址:http://www.cnblogs.com/kerrycode/p/4391859.html 谢谢潇湘隐者,谢谢老大 在Linux系统中,如何去搜索一些比较大的文件呢?下面我整理了一下在 ...
- Linux如何查找大文件或目录总结及在全部目录中查找
在Windows系统中,我们可以使用TreeSize工具查找一些大文件或文件夹,非常的方便高效,在Linux系统中,如何去搜索一些比较大的文件呢?下面我整理了一下在Linux系统中如何查找大文件或文件 ...
- Linux下查找大文件以及目录
转自:http://www.cnblogs.com/kerrycode/p/4391859.html 在Windows系统中,我们可以使用TreeSize工具查找一些大文件或文件夹,非常的方便高效,在 ...
- Linux系统中如何查找大文件或文件夹的方法
在Windows系统中,我们可以使用TreeSize工具查找一些大文件或文件夹,非常的方便高效,在Linux系统中,如何去搜索一些比较大的文件呢?下面我整理了一下在Linux系统中如何查找大文件或文件 ...
- linux查找大文件命令
测试服务器用久了,如果没有运行自动清除日志的脚本,会导致硬盘空间不足,应用.数据库.环境等启动不了: 如果你对系统不是特别熟悉,就无法知道那些占用空间的日志或缓存文件在哪里,这时,我们就可以利用查找大 ...
- centos磁盘满了,查找大文件并清理
今天发现vps敲入crontab -e 居然提示 “Disk quota exceeded” 无法编辑.于是"df -h"查了查发现系统磁盘空间使用100%了.最后定位到是/var ...
随机推荐
- P2742 [USACO5.1]圈奶牛Fencing the Cows
题目描述 农夫约翰想要建造一个围栏用来围住他的奶牛,可是他资金匮乏.他建造的围栏必须包括他的奶牛喜欢吃草的所有地点.对于给出的这些地点的坐标,计算最短的能够围住这些点的围栏的长度. 输入输出格式 输入 ...
- exsi中的虚拟机添加磁盘后虚拟机中磁盘不出现
exsi中的虚拟机添加磁盘后虚拟机中磁盘不出现解决: 计算机---> 管理: 这里可以选择磁盘,格式,分区, 改盘符等操作
- 我的Java历程_写出这个数
lzJava基础进行中,今天偶然间看到的一个题目: 读入一个自然数n,计算其各位数字之和,用汉语拼音写出和的每一位数字.如下代码: import java.util.*;public class Ma ...
- js 将数组中的每一项安装奇偶重新组合成一个数组对象
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...
- NOIp2018模拟赛四十
今天太晚了...题解到时候补吧(flag立好) 成绩:100+0+0=100 感觉A题本质暴力贪心?C题一道水题我居然没做...亏爆 A:[agc011e]increasing numbers B:[ ...
- [codevs3955]最长严格上升子序列(加强版)
题目大意:给你一个序列,要你求该序列中最长严格上升子序列的长度. 解题思路:此题算是一道LIS模板题.普通的$O(n^2)$的LIS是会TLE的,因为$n\le 1000000$,所以此题要用单调队列 ...
- 重载和const形参
1.int lookup(string p); 2.int lookup(const string p);//同1 3.int lookup(string *);//传入一个指针,指针指向string ...
- 紫书 习题 8-15 UVa 1617 (贪心)
先排序, 然后每个线段先放右端点, 然后往下放, 如果不能放就整体往左移动, 当不能往左移动的时候就ans++ 开始下一个整块.判断能不能向左移动要用一个变量储存每个已经放了的区间中线段与左端点距离的 ...
- python set元素访问
python中集合set主要利用其唯一性,及并集|.交集&等操作,但不可以直接通过下标进行访问,必须访问时可以将其转换成list再访问 x={1,2,5} y=list(x) a=y[1] a ...
- 【codeforces 255D】Mr. Bender and Square
[题目链接]:http://codeforces.com/problemset/problem/255/D [题意] 给你一个n*n的方框; 给你一个方块;(以下说的方块都是单位方块) 每一秒钟,可以 ...