任何修补Python足够长的人都被以下问题咬伤(或撕成碎片):
def foo(a=[]):
a.append(5)
return a
Run Code Online (Sandbox Code Playgroud)
Python新手希望这个函数总能返回一个只包含一个元素的列表:[5]
.结果却非常不同,而且非常惊人(对于新手来说):
>>> foo()
[5]
>>> foo()
[5, 5]
>>> foo()
[5, 5, 5]
>>> foo()
[5, 5, 5, 5]
>>> foo()
Run Code Online (Sandbox Code Playgroud)
我的一位经理曾经第一次遇到这个功能,并称其为该语言的"戏剧性设计缺陷".我回答说这个行为有一个潜在的解释,如果你不理解内部,那确实非常令人费解和意想不到.但是,我无法回答(对自己)以下问题:在函数定义中绑定默认参数的原因是什么,而不是在函数执行时?我怀疑经验丰富的行为有实际用途(谁真的在C中使用静态变量,没有繁殖错误?)
编辑:
巴泽克提出了一个有趣的例子.再加上你的大部分评论和特别是Utaal,我进一步阐述了:
>>> def a():
... print("a executed")
... return []
...
>>>
>>> def b(x=a()):
... x.append(5)
... print(x)
...
a executed
>>> b()
[5]
>>> b()
[5, 5]
Run Code Online (Sandbox Code Playgroud)
对我而言,似乎设计决策是相对于放置参数范围的位置:在函数内部还是"与它一起"?
在函数内部进行绑定意味着在调用函数时x
有效地绑定到指定的默认值,而不是定义,这会产生一个深层次的缺陷:def
在某种意义上,该行将是"混合"的(部分绑定)函数对象)将在定义时发生,并在函数调用时发生部分(默认参数的赋值).
实际行为更加一致:执行该行时,该行的所有内容都会得到评估,这意味着在函数定义中.
python language-design least-astonishment default-parameters
我希望JavaScript函数具有可选参数,我将其设置为默认值,如果未定义该值,则使用该参数.在Ruby中你可以这样做:
def read_file(file, delete_after = false)
# code
end
Run Code Online (Sandbox Code Playgroud)
这是否适用于JavaScript?
function read_file(file, delete_after = false) {
// Code
}
Run Code Online (Sandbox Code Playgroud) 我遇到了一些具有以下结构的Java代码:
public MyParameterizedFunction(String param1, int param2)
{
this(param1, param2, false);
}
public MyParameterizedFunction(String param1, int param2, boolean param3)
{
//use all three parameters here
}
Run Code Online (Sandbox Code Playgroud)
我知道在C++中我可以为参数指定一个默认值.例如:
void MyParameterizedFunction(String param1, int param2, bool param3=false);
Run Code Online (Sandbox Code Playgroud)
Java是否支持这种语法?有没有理由说这两步语法更可取?
我有这个脚本:
CREATE FUNCTION dbo.CheckIfSFExists(@param1 INT, @param2 BIT = 1 )
RETURNS BIT
AS
BEGIN
IF EXISTS ( bla bla bla )
RETURN 1;
RETURN 0;
END
GO
Run Code Online (Sandbox Code Playgroud)
我想以这种方式在一个过程中使用它:
IF dbo.CheckIfSFExists( 23 ) = 0
SET @retValue = 'bla bla bla';
Run Code Online (Sandbox Code Playgroud)
但我得到错误:
为程序或函数dbo.CheckIfSFExists提供的参数数量不足.
为什么不起作用?
如果DateTime是一个对象,并且默认的C#参数只能被赋予编译时常量,那么如何为DateTime等对象提供默认值?
我正在尝试使用构造函数初始化POCO中的值,使用带有默认值的命名参数.
我想我可以在Python 2的函数调用中使用可变长度位置参数之后的命名参数,但是SyntaxError
在导入python类时我得到了一个.我正在使用以下"get"方法编写,例如:
class Foo(object):
def __init__(self):
print "You have created a Foo."
def get(self, *args, raw=False, vars=None):
print len(args)
print raw
print vars
Run Code Online (Sandbox Code Playgroud)
错误看起来像:
def get(self, *args, raw=False, vars=None):
^
SyntaxError: invalid syntax
Run Code Online (Sandbox Code Playgroud)
我希望能够通过几种方式调用该方法:
f = Foo()
f.get(arg1, arg2)
f.get(arg1, raw=True)
f.get(arg1, arg2, raw=True, vars=something)
Run Code Online (Sandbox Code Playgroud)
等等
python python-2.x variadic-functions named-parameters default-parameters
可能重复:
作为实例方法的结果的参数的默认值
虽然可以在python中将默认值设置为函数参数:
def my_function(param_one='default')
...
Run Code Online (Sandbox Code Playgroud)
似乎无法访问当前实例(self):
class MyClass(..):
def my_function(self, param_one=self.one_of_the_vars):
...
Run Code Online (Sandbox Code Playgroud)
我的问题:
我偶然发现了Scott Meyers的" 嵌入式环境中的有效C++"中的一个例子,其中描述了两种使用默认参数的方法:一种被描述为昂贵而另一种被描述为更好的选择.
我错过了为什么第一个选项可能比另一个更昂贵的解释.
void doThat(const std::string& name = "Unnamed"); // Bad
const std::string defaultName = "Unnamed";
void doThat(const std::string& name = defaultName); // Better
Run Code Online (Sandbox Code Playgroud) 请向我解释为什么以下代码符合并完美运行.我很迷茫.
#include<iostream>
template<class A = int, class B=double>
class Base
{};
template<class B>
class Base <int, B>
{
public:
Base()
{
std::cout<<"it works!!!!!\n";
}
};
int main()
{
Base<> base; // it prints "it works!!!!!"
return 0;
}
Run Code Online (Sandbox Code Playgroud)
它不应该属于模板类Base的通用形式吗?
function ×3
python ×3
c++ ×2
parameters ×2
arguments ×1
c ×1
c# ×1
defaults ×1
java ×1
javascript ×1
methods ×1
overloading ×1
performance ×1
python-2.x ×1
t-sql ×1
templates ×1