我们知道,给函数常用的参数值设定为参数的默认值,可以降低函数调用的难度。偏函数也可以做到这一点。
假如我们有如下这样的一个函数,可以根据输入的文件路径,根据用户所需要的文件类型得到对应的文件类型列表
import os
path = 'c:\\'
def filelist(filepath, filetype = 'all'):
alldata = os.listdir(filepath)
datalist = []
if filetype == 'all':
datalist = alldata
if filetype == 'dir':
for dir in alldata:
if os.path.isdir(filepath + dir) is True:
datalist.append(dir)
if filetype == 'file':
for f in alldata:
if os.path.isfile(filepath + f) is True:
datalist.append(f)
return datalist
result1 = filelist(path)
print(f'result1:\n{result1}')
result2 = filelist(path, 'dir')
print(f'result2:\n{result2}')
result3 = filelist(path, 'file')
print(f'result3:\n{result3}')
>>
result1:
['$360Section', '$Recycle.Bin', '$SysReset', '$Windows.~WS', '360Rec', '360SANDBOX', 'ActiveTcl', 'aow_drv.log', 'AppData', 'Boot', 'bootmgr', 'BOOTNXT', 'BOOTSECT.BAK', 'chromedriver.exe', 'Config.Msi', 'Documents and Settings', 'Downloads', 'Drivers', 'ESD', 'hiberfil.sys', 'install.log', 'LibAntiPrtSc_ERROR.log', 'LibAntiPrtSc_INFORMATION.log', 'NVIDIA', 'OneDriveTemp', 'OnKeyDetector.log', 'pagefile.sys', 'PerfLogs', 'Program Files', 'Program Files (x86)', 'Program1', 'Program2', 'Program3', 'ProgramData', 'Recovery', 'sqlite', 'swapfile.sys', 'System Volume Information', 'Tcl', 'Users', 'Windows', 'Windows.old']
result2:
['$360Section', '$Recycle.Bin', '$SysReset', '$Windows.~WS', '360Rec', '360SANDBOX', 'ActiveTcl', 'AppData', 'Boot', 'Config.Msi', 'Documents and Settings', 'Downloads', 'Drivers', 'ESD', 'NVIDIA', 'OneDriveTemp', 'PerfLogs', 'Program Files', 'Program Files (x86)', 'Program1', 'Program2', 'Program3', 'ProgramData', 'Recovery', 'sqlite', 'System Volume Information', 'Tcl', 'Users', 'Windows', 'Windows.old']
result3:
['aow_drv.log', 'bootmgr', 'BOOTNXT', 'BOOTSECT.BAK', 'chromedriver.exe', 'hiberfil.sys', 'install.log', 'LibAntiPrtSc_ERROR.log', 'LibAntiPrtSc_INFORMATION.log', 'OnKeyDetector.log', 'pagefile.sys', 'swapfile.sys']
但假如只得到文件列表的需求比较多,为了调用方便,一种方法是改造原来的函数来得新函数,如下面是将默认值改为file即可.
def filelist(filepath, filetype = 'file'):n: list
'''
alldata = os.listdir(filepath)
datalist = []
if filetype == 'all':
datalist = alldata
if filetype == 'dir':
for dir in alldata:
if os.path.isdir(filepath + dir) is True:
datalist.append(dir)
if filetype == 'file':
for f in alldata:
if os.path.isfile(filepath + f) is True:
datalist.append(f)
return datalist
但还有一种方式,就是偏函数,在不改变函数的情况下,用一次极简的方式创建一个新函数。
import os
from functools import partial
path = 'c:\\'
def filelist(filepath, filetype = 'all'):
alldata = os.listdir(filepath)
datalist = []
if filetype == 'all':
datalist = alldata
if filetype == 'dir':
for dir in alldata:
if os.path.isdir(filepath + dir) is True:
datalist.append(dir)
if filetype == 'file':
for f in alldata:
if os.path.isfile(filepath + f) is True:
datalist.append(f)
return datalist
# result1 = filelist(path)
# print(f'result1:\n{result1}')
#
# result2 = filelist(path, 'dir')
# print(f'result2:\n{result2}')
result3 = filelist(path, 'file')
print(f'result3:\n{result3}')
filelist_file = partial(filelist, filetype = 'file')
fileR = filelist_file(path)
print(fileR)
>>
result3:
['aow_drv.log', 'bootmgr', 'BOOTNXT', 'BOOTSECT.BAK', 'chromedriver.exe', 'hiberfil.sys', 'install.log', 'LibAntiPrtSc_ERROR.log', 'LibAntiPrtSc_INFORMATION.log', 'OnKeyDetector.log', 'pagefile.sys', 'swapfile.sys']
['aow_drv.log', 'bootmgr', 'BOOTNXT', 'BOOTSECT.BAK', 'chromedriver.exe', 'hiberfil.sys', 'install.log', 'LibAntiPrtSc_ERROR.log', 'LibAntiPrtSc_INFORMATION.log', 'OnKeyDetector.log', 'pagefile.sys', 'swapfile.sys']
仅一行,就创建了一个新函数,结果与预期一致。
原来的函数保留,偏函数在创建新函数时相当于将原来函数还的部分参数固定了,这样调用起来就更方便了.