我正在编写一个小应用程序,必须在执行之前执行一些"健全性检查".(例如,健全性检查:测试某条路径是否可读/可写/存在)
代码:
import logging
import os
import shutil
import sys
from paths import PATH
logging.basicConfig(level=logging.DEBUG)
log = logging.getLogger('sf.core.sanity')
def sanity_access(path, mode):
ret = os.access(path, mode)
logfunc = log.debug if ret else log.warning
loginfo = (os.access.__name__, path, mode, ret)
logfunc('%s(\'%s\', %s)==%s' % loginfo)
return ret
def sanity_check(bool_func, true_func, false_func):
ret = bool_func()
(logfunc, execfunc) = (log.debug, true_func) if ret else \
(log.warning, false_func)
logfunc('exec: %s', execfunc.__name__)
execfunc()
def sanity_checks():
sanity_check(lambda: sanity_access(PATH['userhome'], os.F_OK), \
lambda: None, sys.exit)
Run Code Online (Sandbox Code Playgroud)
我的问题与sanity_check功能有关.
这个函数有3个参数(bool_func,true_func,false_func).如果bool_func(这是测试函数,返回一个布尔值)失败,则true_func执行,否则false_func执行获取.
1) lambda: None有点蹩脚,因为例如,如果sanity_access返回True,则lambda: None执行,输出打印将是:
DEBUG:sf.core.sanity:access('/home/nomemory', 0)==True
DEBUG:sf.core.sanity:exec: <lambda>
Run Code Online (Sandbox Code Playgroud)
所以在日志中不太清楚哪些函数被执行了.日志只包含<lambda>.是否有一个默认函数什么都不做,可以作为参数传递?它是一种返回lambda中正在执行的第一个函数的名称的方法吗?
或者,如果"没有"作为参数发送,则不记录"exec"的方法?
什么是无功/无效功能?
sanity_check(lambda: sanity_access(PATH['userhome'], os.F_OK), \
<do nothing, but show something more useful than <lambda>>, sys.exit)
Run Code Online (Sandbox Code Playgroud)
另外一个问题,为什么lambda: pass不是lambda: None不工作?
我通常会删除这篇文章因为THC4k看到了所有的复杂性并正确地重写了你的功能.然而在不同的背景下,K组合器技巧可能会派上用场,所以我会把它留下来.
没有内置可以做你想要的AFIK.我相信你想要K组合器(链接出现在另一个问题上),可以编码为
def K_combinator(x, name):
def f():
return x
f.__name__ = name
return f
none_function = K_combinator(None, 'none_function')
print none_function()
Run Code Online (Sandbox Code Playgroud)
当然,如果这只是一次性,你可以做到
def none_function():
return None
Run Code Online (Sandbox Code Playgroud)
但是你不能说"K组合".'K_combinator'方法的另一个优点是你可以将它传递给函数,例如,
foo(call_back1, K_combinator(None, 'name_for_logging'))
Run Code Online (Sandbox Code Playgroud)
至于你的第二个陈述,只允许表达式lambda.pass是一份声明.因此,lambda: pass失败了.
您可以通过删除第一个参数周围的lambda来略微简化您对完整性检查的调用.
def sanity_check(b, true_func, false_func):
if b:
logfunc = log.debug
execfunc = true_func
else:
logfunc = log.warning
execfunc = false_func
logfunc('exec: %s', execfunc.__name__)
execfunc()
def sanity_checks():
sanity_check(sanity_access(PATH['userhome'], os.F_OK),
K_combinator(None, 'none_func'), sys.exit)
Run Code Online (Sandbox Code Playgroud)
这更具可读性(主要是通过将三元运算符扩展为if).在boolfunc没有做任何事情,因为sanity_check不添加任何参数调用.不妨只是打电话而不是把它包裹在lambda中.
什么是所有lambdas没有任何目的?好吧,也许可选的参数会对你有所帮助:
def sanity_check( test, name='undefined', ontrue=None, onfalse=None ):
if test:
log.debug(name)
if ontrue is not None:
ontrue()
else:
log.warn( name )
if onfalse is not None:
onfalse()
def sanity_checks():
sanity_check(sanity_access(PATH['userhome'], os.F_OK), 'test home',
onfalse=sys.exit)
Run Code Online (Sandbox Code Playgroud)
但是你真的过于复杂了.
| 归档时间: |
|
| 查看次数: |
22288 次 |
| 最近记录: |