iter函數用法簡述
Python 3中關於iter(object[, sentinel)]方法有兩個參數。
使用iter(object)這種形式比較常見。
iter(object, sentinel)這種形式一般較少使用
1,iter(object)
Python官方文檔對於這種形式的解釋很容易理解。
此時,object必須是集合對象,且支持迭代協議(iteration protocol)或者支持序列協議(sequence protocol)。
說白了,也就是實現了__iter__()方法或者__getitem__()方法。
l = [1, 2, 3]
for i in iter(l):
print(i)
2,iter(object, sentinel)
Python官方文檔對於這種形式的解釋是:“ If the second argument, sentinel, is given, then object must be a callable object. The iterator created in this case will call object with no arguments for each call to its __next__() method; if the value returned is equal to sentinel,StopIteration will be raised, otherwise the value will be returned.”。
這句話的意思是說:如果傳遞了第二個參數,則object必須是一個可調用的對象(如,函數)。此時,iter創建了一個迭代器對象,每次調用這個迭代器對象的__next__()方法時,都會調用object。
如果__next__的返回值等於sentinel,則拋出StopIteration異常,否則返回下一個值。
class TestIter(object):
def __init__(self):
self.l=[1,2,3,4,5]
self.i=iter(self.l)
def __call__(self): #定義了__call__方法的類的實例是可調用的
item = next(self.i)
print ("__call__ is called,which would return",item)
return item
def __iter__(self): #支持迭代協議(即定義有__iter__()函數)
print ("__iter__ is called!!")
return iter(self.l)
t = TestIter() # t是可調用的
t1 = iter(t, 3) # t必須是callable的,否則無法返回callable_iterator
print(callable(t))
for i in t1:
print(i)
# 它每次在調用的時候,都會調用__call__函數,並且最后輸出3就停止了。
True
__call__ is called,which would return 1
1
__call__ is called,which would return 2
2
__call__ is called,which would return 3
在文件讀取時使用:
import os
import hashlib
def bytes2human(n):
# 文件大小字節單位轉換
symbols = ('K', 'M', 'G', 'T', 'P', 'E')
prefix = {}
for i, s in enumerate(symbols):
# << 左移” 左移一位表示乘2 即1 << 1=2,二位就表示4 即1 << 2=4,
# 10位就表示1024 即1 << 10=1024 就是2的n次方
prefix[s] = 1 << (i + 1) * 10
for s in reversed(symbols):
if n >= prefix[s]:
value = float(n) / prefix[s]
return '%.2f%s' % (value, s)
return "%sB" % n
def get_md5(file_path):
"""
得到文件MD5
:param file_path:
:return:
"""
if os.path.isfile(file_path):
file_size = os.stat(file_path).st_size
md5_obj = hashlib.md5() # hashlib
f = open(file_path, 'rb') # 打開文件
read_size = 0
while read_size < file_size:
read_byte = f.read(8192)
md5_obj.update(read_byte) # update md5
read_size += len(read_byte)
hash_code = md5_obj.hexdigest() # get md5 hexdigest
f.close()
print('file: [{}] \nsize: [{}] \nmd5: [{}]'.format(
file_path, bytes2human(read_size), hash_code))
return str(hash_code)
def get_filemd5(file_path):
# 使用迭代器讀取文件獲得MD5
if os.path.isfile(file_path):
file_size = os.stat(file_path).st_size
md5_obj = hashlib.md5() # hashlib
f = open(file_path, 'rb') # 打開文件
read_size = 1024
for chunk in iter(lambda: f.read(read_size), b''): # 使用迭代器讀取文件獲得MD5
md5_obj.update(chunk)
hash_code = md5_obj.hexdigest() # get md5 hexdigest
f.close()
print('file: [{}] \nsize: [{}] \nmd5: [{}]'.format(
file_path, bytes2human(file_size), hash_code))
return str(hash_code)
if __name__ == '__main__':
md5 = get_md5(
r'C:\README.md')
md5_1 = get_filemd5(
r'C:\README.md')
------------------------輸出
file: [C:\README.md]
size: [941B]
md5: [d22b8f76dcd8cfbfd4669d9d8101077e]
file: [C:\README.md]
size: [941B]
md5: [d22b8f76dcd8cfbfd4669d9d8101077e]
