C++标准库函数按值获取functor(函数指针或函数对象)参数,如下所示:
template <typename F>
void apply(F func)
{
func();
}
Run Code Online (Sandbox Code Playgroud)
......但是通过Universal Reference传递仿函数会不会更好?像这样:
template <typename F>
void apply(F&& func)
{
func();
}
Run Code Online (Sandbox Code Playgroud)
这样,您可以传递维护状态的函数对象,并在返回高阶函数后访问该(可能已修改的)状态.
考虑具有默认参数的典型函数:
def f(accuracy=1e-3, nstep=10):
...
Run Code Online (Sandbox Code Playgroud)
这很紧凑,易于理解.但是,如果我们有另一个功能g,将来电f,我们要传递的一些参数g来f?这样做的一种自然方式是:
def g(accuracy=1e-3, nstep=10):
f(accuracy, nstep)
...
Run Code Online (Sandbox Code Playgroud)
这种做法的问题在于可选参数的默认值会重复出现.通常在传播这样的默认参数时,需要在上部函数(g)中使用与下部函数(f)中相同的默认值,因此任何时候默认更改都f需要通过调用它的所有函数并更新默认值他们将传播给他们的任何论据f.
另一种方法是使用占位符参数,并在函数内填写其值:
def f(accuracy=None, nstep=None):
if accuracy is None: accuracy = 1e-3
if nstep is None: nstep=10
...
def g(accuracy=None, nstep=None):
f(accuracy, nstep)
...
Run Code Online (Sandbox Code Playgroud)
现在调用函数不需要知道f默认值是什么.但是f界面现在有点麻烦,而且不太清楚.这是没有显式默认参数支持的语言中的典型方法,如fortran或javascript.但是如果一个人在python中以这种方式完成所有事情,那么就会丢掉大部分语言的默认参数支持.
有没有比这两个更好的方法?这样做的标准,pythonic方式是什么?
我有一些任务需要解决,目前最重要的部分是使脚本尽可能节省时间.我试图优化的一个要素是其中一个函数中的memoization.
所以我的问题是:以下3-4种方法中哪一种是在Python中实现memoization的最有效/最快的方法?
我只提供了代码作为示例 - 如果其中一种方法更有效,但在我提到的情况下,请分享您所知道的内容.
此解决方案通常显示为示例memoization,但我不确定它的效率如何.我听说使用全局变量(在这种情况下,它是从外部变量而不是全局变量)效率较低.
def main():
memo = {}
def power_div(n):
try:
return memo[n]
except (KeyError):
memo[n] = (n ** 2) % 4 # example expression, should not matter
return memo[n]
# extensive usage of power_div() here
Run Code Online (Sandbox Code Playgroud)
我发现在过去使用默认的可变参数从外部作用域传递变量,当Python首先在本地作用域中搜索变量,然后在全局作用域中,跳过非局部作用域(在本例中为范围内)功能main()).因为默认参数仅在定义函数时初始化,并且只能在内部函数内部访问,因此它可能更有效吗?
def main():
def power_div(n, memo={}):
try:
return memo[n]
except (KeyError):
memo[n] = (n ** 2) % 4 # example expression, should not matter
return memo[n]
# extensive usage of power_div() …Run Code Online (Sandbox Code Playgroud) python performance memoization static-variables argument-passing
在大学编程竞赛中提出了以下问题.我们被要求猜测输出和/或解释它的工作原理.不用说,我们都没有成功.
main(_){write(read(0,&_,1)&&main());}
Run Code Online (Sandbox Code Playgroud)
一些简短的谷歌搜索引导我到这个确切的问题,问codegolf.stackexchange.com:
https://codegolf.stackexchange.com/a/1336/4085
在那里,它解释了它的作用:Reverse stdin and place on stdout但不是如何.
我也在这个问题上找到了一些帮助:主要的三个论点,以及其他混淆的技巧,
但它仍然没有解释如何main(_),&_并且&&main()有效.
我的问题是,这些语法如何工作?它们是我应该知道的,因为它们仍然相关吗?
如果不是直接的答案,我会感激任何指针(资源链接等).
这个问题涉及在automator osx中运行的bash脚本.我正在使用automator动作来获取和过滤来自finder的一堆文件引用.然后我通过自动机器操作将该文件夹的名称附加到该列表中.然后,Automator将这些参数提供给名为"run shell script"的操作.我不确定automator究竟是如何调用脚本的,但是当回显时,参数列表看起来像这样:echo "$@"
/ Volumes/G-Raid/Online/WAV_TEST/Testbok 50/01/01000 43-001.wav/Volumes/G-Raid/Online/WAV_TEST/Testbok 50/02/02000 43-002.wav/Volumes/G-Raid /在线/ WAV_TEST/Testbok 50/03/03000 43-003.wav/Volumes/G-Raid/Online/WAV_TEST/Testbok 50
在这种情况下,路径为3个文件和一个文件夹.
在shell脚本中,我启动了一个名为ripcheckc*的应用程序,其中args从automator传递,减去列表中的最后一个参数(文件夹).
我用它来删除最后一个参数:
_args=( "$@" )
unset _args[${#_args[@]}-1]
Run Code Online (Sandbox Code Playgroud)
这是echo $_args:
/ Volumes/G-Raid/Online/WAV_TEST/Testbok 50/01/01000 43-001.wav/Volumes/G-Raid/Online/WAV_TEST/Testbok 50/02/02000 43-002.wav/Volumes/G-Raid/Online/WAV_TEST/Testbok 50/03/03000 43-003.wav
与以前相同,但没有文件夹.
现在,如果我使用"$@"as参数运行ripcheckc 它可以工作(但由于参数列表中的最后一个路径,以后会失败)如果我使用${_args[@]}该应用程序将只是静默中止.当我回显$@并且_args输出看起来相同,除了最后一个参数.
我的问题是 - $ @和$ _args之间的区别是第一个有效输入而第二个没有?
*该应用程序是ripcheckc
我希望我的问题有道理.
编辑:解决了.
在Python中,我理解默认参数出现在最后,非默认参数不能遵循默认参数.那样就好.例如:
>>> def foo(x=0, y):
return x, y
SyntaxError: non-default argument follows default argument
Run Code Online (Sandbox Code Playgroud)
这没关系.
但是,当我想要第一个参数应该是默认参数的情况呢?例如,从上面的代码可以看出,x必须是第一个参数,它应该具有默认值0.
是否有可能做到这一点?我问,因为即使在range函数中,我猜它是这样的:
def range(start=0, end):
pass
Run Code Online (Sandbox Code Playgroud)
那么这是如何完成的,如果不可能,这是如何实现的range呢?请注意,我坚持认为第一个参数是默认值,即整个点.我用它range作为一个例子,因为它完全符合我的问题.当然,一个可以实现range的def range(end, start=0),但是这不是重点.
我想将一个对象作为参数传递给字符串中的Onclick函数.像下面这样的东西:
function myfunction(obj,parentobj){
var o=document.createElement("div");
o.innerHTML='<input type="button" onclick="somelistener(' + obj + ')" />';
parentobj.appendChild(o.firstChild);
}
Run Code Online (Sandbox Code Playgroud)
显然,这不起作用.任何人有任何想法?谢谢!
一个更完整的版本,正如@Austin所建议的那样
<!DOCTYPE html>
<html>
<body>
<style type="text/css">
</style>
<p id="test">test</p>
<p id="objectid"></p>
<script>
function test(s){
document.getElementById("test").innerHTML+=s;
}
function somelistener(obj){
test(obj.id);
}
function myfunction(obj,parentobj){
var o=document.createElement("div");
o.innerHTML='<input type="button" onclick="somelistener(' + obj + ')" />';
o.onclick = function () {
someListener(obj)
}
parentobj.appendChild(o.firstChild);
}
myfunction(document.getElementById("objectid"),document.getElementById("test"));
</script>
</body>
</html>
Run Code Online (Sandbox Code Playgroud) 似乎最先进的编译器将堆栈传递的参数视为只读.请注意,在x86调用约定中,调用者将参数压入堆栈,并且被调用者使用堆栈中的参数.例如,以下C代码:
extern int goo(int *x);
int foo(int x, int y) {
goo(&x);
return x;
}
Run Code Online (Sandbox Code Playgroud)
clang -O3 -c g.c -S -m32在OS X 10.10中编译成:
.section __TEXT,__text,regular,pure_instructions
.macosx_version_min 10, 10
.globl _foo
.align 4, 0x90
_foo: ## @foo
## BB#0:
pushl %ebp
movl %esp, %ebp
subl $8, %esp
movl 8(%ebp), %eax
movl %eax, -4(%ebp)
leal -4(%ebp), %eax
movl %eax, (%esp)
calll _goo
movl -4(%ebp), %eax
addl $8, %esp
popl %ebp
retl
.subsections_via_symbols
Run Code Online (Sandbox Code Playgroud)
这里,首先加载参数x(8(%ebp))%eax; 然后存储-4(%ebp) …
我想写一个模板函数,它与a std::stack<T>和一个实例做一些事情T,例如:
template<class StackType> inline
bool some_func( StackType const &s, typename StackType::value_type const &v ) {
// ...
}
Run Code Online (Sandbox Code Playgroud)
我通过v引用传递的原因当然是针对StackType::value_typea struct或者class不按值复制整个对象的情况进行优化.
但是,如果它StackType::value_type是一个"简单"类型int,那么它当然更简单地通过值传递它.
的问题是:对于一个类型,如int,将成为int const&作为一个正式的参数在上面的功能,将编译器优化掉参考和简单地通过值传递呢?
我正在研究一些遗留的C代码.原始代码是在90年代中期编写的,目标是那个时代的Solaris和Sun的C编译器.当前版本在GCC 4下编译(虽然有许多警告),它似乎有效,但我正在努力整理它 - 我想尽可能多地挤出潜在的错误,因为我确定了可能需要的东西.使其适应64位平台,以及编译器以外的编译器.
我在这方面的主要活动之一是确保所有函数都有完整的原型(许多人都没有),在这种情况下我发现了一些调用函数(以前没有原型)的代码,其参数少于函数定义声明.函数实现确实使用了缺少参数的值.
例:
impl.c:
int foo(int one, int two) {
if (two) {
return one;
} else {
return one + 1;
}
}
Run Code Online (Sandbox Code Playgroud)
client1.c:
extern foo();
int bar() {
/* only one argument(!): */
return foo(42);
}
Run Code Online (Sandbox Code Playgroud)
client2.c:
extern int foo();
int (*foop)() = foo;
int baz() {
/* calls the same function as does bar(), but with two arguments: */
return (*foop)(17, 23);
}
Run Code Online (Sandbox Code Playgroud)
问题:是否定义了缺少参数的函数调用的结果?如果是这样,函数将为未指定的参数接收什么值?否则,Sun C编译器的ca. 1996年(对于Solaris,而不是VMS)展示了一种可预测的特定于实现的行为,我可以通过向受影响的调用添加特定的参数值来模拟这种行为吗?
argument-passing ×10
c ×3
python ×3
c++ ×2
automator ×1
bash ×1
c++11 ×1
default ×1
functor ×1
javascript ×1
memoization ×1
optimization ×1
performance ×1
shell ×1
stack ×1
templates ×1
x86 ×1