通过“无”作为函数参数(其中参数是函数)
我正在编写一个小型应用程序,在进入执行之前必须执行一些“健全性检查”。 (例如,健全性检查:测试某个路径是否可读/可写/存在)
代码:
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)
我的问题与 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>
所以日志中不会很清楚执行了什么函数。日志将仅包含
。是否有一个默认函数不执行任何操作并且可以作为参数传递?这是返回 lambda 内执行的第一个函数的名称的方法吗?
或者如果“无”作为参数发送,则不记录“exec”的方法?
函数的 none / do-nothing 等价物是什么?
sanity_check(lambda: sanity_access(PATH['userhome'], os.F_OK), \
<do nothing, but show something more useful than <lambda>>, sys.exit)
另外一个问题,为什么 lambda: pass
而不是 lambda: None
不起作用?
I am writing a small app that has to perform some 'sanity checks' before entering execution. (eg. of a sanity check: test if a certain path is readable / writable / exists)
The code:
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)
My question is related to the sanity_check
function.
This function takes 3 parameters (bool_func
, true_func
, false_func
). If the bool_func
(which is the test function, returning a boolean value) fails, true_func
gets executed, else the false_func
gets executed.
1) lambda: None
is a little lame , because for example if the sanity_access returns True, lambda: None
gets executed, and the output printed will be:
DEBUG:sf.core.sanity:access('/home/nomemory', 0)==True
DEBUG:sf.core.sanity:exec: <lambda>
So it won't be very clear in the logs what function got executed. The log will only contain <lambda>
. Is there a default function that does nothing and can be passed as a parameter ? Is it a way to return the name of the first function that is being executed inside a lambda ?
Or a way not to log that "exec" if 'nothing' is sent as a paramter ?
What's the none / do-nothing equivalent for functions ?
sanity_check(lambda: sanity_access(PATH['userhome'], os.F_OK), \
<do nothing, but show something more useful than <lambda>>, sys.exit)
Additional question, why is lambda: pass
instead of lambda: None
not working ?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
所有没有任何作用的 lambda 是怎么回事?好吧,也许可选参数会对您有所帮助:
但是您确实使事情变得过于复杂了。
What's with all the lambdas that serve no purpose? Well, maybe optional arguments will help you a bit:
But you are really overcomplicating things.
更新
我通常会删除这篇文章,因为 THC4k 看透了所有的复杂性并正确地重写了你的函数。然而,在不同的上下文中,K 组合器技巧可能会派上用场,所以我将保留它。
没有内置函数可以完成您想要的 AFIK。我相信您想要 K 组合器 (链接出现在另一个问题上),它可以是当然
,如果这只是一次性的,那么你可以这样做
,但是你就不能说“K组合器”。 “K_combinator”方法的另一个优点是您可以将其传递给函数,例如,
对于第二个语句,
lambda
中只允许使用表达式。pass
是一个语句。因此,lambda: pass
失败。您可以通过删除第一个参数周围的 lambda 来稍微简化对健全性检查的调用。
这更具可读性(主要是将三元运算符扩展为 if)。
boolfunc
没有执行任何操作,因为sanity_check
没有向调用添加任何参数。不妨直接调用而不是将其包装在 lambda 中。update
I would normally delete this post because THC4k saw through all the complexity and rewrote your function correctly. However in a different context, the K combinator trick might come in handy, so I'll leave it up.
There is no builtin that does what you want AFIK. I believe that you want the K combinator (the link came up on another question) which can be encoded as
of course if this is just a one off then you could just do
But then you don't get to say "K combinator". Another advantage of the 'K_combinator' approach is that you can pass it to functions, for example,
as for your second statement, only expressions are allowed in
lambda
.pass
is a statement. Hence,lambda: pass
fails.You can slightly simplify your call to sanity check by removing the lambda around the first argument.
This is more readable (largely from expanding the ternary operator into an if). the
boolfunc
wasn't doing anything becausesanity_check
wasn't adding any arguments to the call. Might as well just call instead of wrapping it in a lambda.您可能需要重新考虑这一点。
可调用对象可以简化您的生活。
You might want to rethink this.
Callable objects can simplify your life.
实际上,您想要的是一个不执行任何操作的函数,但有一个对日志有用的
__name__
。 lambda 函数正在做正是您想要的事情,但是execfunc.__name__
给出的是""
。尝试以下其中一项:您还可以在函数上添加自己的属性:
然后将
execfunc.__name__
更改为getattr(execfunc,'log_info', '')
Actually, what you want is a function which does nothing, but has a
__name__
which is useful to the log. The lambda function is doing exactly what you want, butexecfunc.__name__
is giving"<lambda>"
. Try one of these:You can also put your own attributes on functions:
Then change
execfunc.__name__
togetattr(execfunc,'log_info', '')