可变的默认参数问题[Prothon] [英] mutable default parameter problem [Prothon]

查看:82
本文介绍了可变的默认参数问题[Prothon]的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

正如我们正在解决的疣一样。在Python中修复Prothon,我们有

来自

可变默认参数问题。对于那些不熟悉这个问题的人,

可以在这个Prothon代码示例中看到新手希望下面两个

函数调用打印[1]:


def f(list = []):

print list.append!(1)


f()#打印[1]

f()#prints [1,1]


这不仅仅是一个新手问题。即使是专家也发现自己有这样的事情来做这样的事情,这会浪费编程工作:


def f(list = None):

if list == None:list = []


我们现在在Prothon邮件列表中有三个提案来解决这个问题。

我我希望将这些内容从Python列表中反弹出去,因为这将会使得b / b
可能会对移植到Prothon的Python代码产生重大影响,而且我们可以使用更多的b $ b建议。


1)只允许不可变对象作为形式参数的默认值。在

Prothon不可变对象是明确定义的,因为它们有一个不可变的标志

写保护它们。这个(正如下面的其他解决方案)只会以一种浅薄的方式解决问题,因为人们仍然可以拥有类似于可变对象元组的东西,并在更深层次。如果

新手将处理这个复杂的事情,那么他们

正在处理引用与副本的整体问题,那就是

a更大的整体问题。


2)当需要默认的

值时,在每次调用时评估一次默认表达式。默认表达式将在函数定义的上下文中评估

(如闭包)。


3)在定义时评估表达式,因为它是现在完成,但随叫随到

时间执行defaultValue.copy()操作。这将是一个浅薄的副本,所以

再次它将是一个浅薄的解决方案。


选择2是我最喜欢的,因为它符合Prothon的动态性质,

但这是一个昂贵的解决方案。选择1是最便宜的解决方案

但它限制了用户。选择1没有帮助第二个代码

样本如上。选择3是一个很好的折衷,因为在Prothon中,object.copy()很快就会很快。


评论?这些不同的提案会破坏多少Python代码?

As we are addressing the "warts" in Python to be fixed in Prothon, we have
come upon the
mutable default parameter problem. For those unfamiliar with the problem,
it can be seen in this Prothon code sample where newbies expect the two
function calls below to both print [ 1 ] :

def f( list=[ ] ):
print list.append!(1)

f() # prints [ 1 ]
f() # prints [ 1, 1 ]

It is more than just a newbie problem. Even experts find themselves having
to do things like this which is a waste of programming effort:

def f( list = None ):
if list == None: list = [ ]

We have three proposals in the Prothon mailing list right now to fix this.
I''d like to bounce these off of the Python list also since this will
possibly make a big difference in Python code ported over to Prothon and we
can always use more advice.

1) Only allow immutable objects as default values for formal parameters. In
Prothon immutable objects are well-defined since they have an immutable flag
that write-protects them. This (as the other solutions below) would only
solve the problem in a shallow way as one could still have something like a
tuple of mutable objects and see the problem at a deeper level. If the
newbie is going to be dealing with something this complex though then they
are dealing with the overall problem of references versus copies and that is
a bigger overall issue.

2) Evaluate the default expression once at each call time when the default
value is needed. The default expression would be evaluated in the context
of the function definition (like a closure).

3) Evaluate the expression at definition time as it is done now, but at call
time do a defaultValue.copy() operation. This would be a shallow copy so
again it would be a shallow solution.

Choice 2 is my favorite in that it matches the dynamic nature of Prothon,
but it is an expensive solution. Choice 1 is the least expensive solution
but it is limiting to the user. Choice 1 does not help the second code
sample above. Choice 3 is a good compromise since an object.copy() is
pretty fast in Prothon.

Comments? How much Python code would these different proposals break?

推荐答案

2004年6月15日星期二15:07:05 -0700,Mark Hahn写道:
On Tue, 15 Jun 2004 15:07:05 -0700, Mark Hahn wrote:
选择2是我最喜欢的,它与Prothon的动态性质相匹配,
但它是一种昂贵的解决方案。选择1是最便宜的解决方案
但它限制了用户。选择1没有帮助第二个代码
上面的样本。选择3是一个很好的折衷,因为在Prothon中object.copy()相当快。

评论?这些不同的提案会破坏多少Python代码?
Choice 2 is my favorite in that it matches the dynamic nature of Prothon,
but it is an expensive solution. Choice 1 is the least expensive solution
but it is limiting to the user. Choice 1 does not help the second code
sample above. Choice 3 is a good compromise since an object.copy() is
pretty fast in Prothon.

Comments? How much Python code would these different proposals break?




我最喜欢2。嗯,实际上我只喜欢2 :-)


我不知道为什么它会很贵,如果贵的话很遗憾,

但它应该适用于大多数情况并且很容易理解。


-

__("< Marcin Kowalczyk

\ __ / qr****@knm.org.pl

^^ http://qrnik.knm.org。 pl / ~qrczak /



I like 2 the most. Well, actually I like only 2 :-)

I''m not sure why it would be expensive, it''s a pity if it''s expensive,
but it should be appropriate for most cases and it''s easy to understand.

--
__("< Marcin Kowalczyk
\__/ qr****@knm.org.pl
^^ http://qrnik.knm.org.pl/~qrczak/


2004年6月15日星期二02:07 pm,Mark Hahn写道:
On Tuesday 15 June 2004 02:07 pm, Mark Hahn wrote:
由于我们正在解决Python中的疣在Prothon中修复,我们已经发现了
可变的默认参数问题。对于那些不熟悉问题的人,可以看到它在这个Prothon代码示例中,新手期望下面的两个函数调用打印[1]:
我们在Prothon邮件中有三个提案现在列出来解决这个问题。
我想将这些内容从Python列表中删除,因为这可能会对移植到Prothon的Python代码产生很大影响,我们
可以随时使用更多建议。


这是一个想法:如果它没有坏掉,就不要修理它。


说真的,你看疣和问题。我看到了记录语义的一个令人愉快的副作用

。确实,新人们对这种行为感到惊讶,但是一旦理解了它就会变得更加强大。


你打算如何计算?像这样的代码:


def F(a,b,cache = {}):

试试:

返回缓存[ (a,b)]

除(IndexError,):

value = cache [(a,b)] = do_some_long_calc(a,b)

返回值


甚至这个:


shared_cache = {}


def F(a,b,cache = shared_cache):

...


当然你可以说这是不好的风格,但反驳的论点是

同样强大:这是相当pythonic和相当可读。


Python是一个工具,当你限制
它的成语。

这些不同的提案会破坏多少Python代码?
As we are addressing the "warts" in Python to be fixed in Prothon, we have
come upon the
mutable default parameter problem. For those unfamiliar with the problem,
it can be seen in this Prothon code sample where newbies expect the two
function calls below to both print [ 1 ] : We have three proposals in the Prothon mailing list right now to fix this.
I''d like to bounce these off of the Python list also since this will
possibly make a big difference in Python code ported over to Prothon and we
can always use more advice.
Here''s an idea: if it ain''t broke, don''t fix it.

Seriously, you see a "wart" and a "problem". I see a pleasant side-effect of
the documented semantics. True, new folks are surprised by the behavior, but
once it''s understood, it becomes more powerful.

How do you intend to account for code like this:

def F(a, b, cache={}):
try:
return cache[(a,b)]
except (IndexError, ):
value = cache[(a,b)] = do_some_long_calc(a,b)
return value

Or even this:

shared_cache = {}

def F(a, b, cache=shared_cache):
...

Of course you can argue that this is bad style, but the counter argument is
just as strong: this is quite pythonic and quite readable.

Python is a tool, and you decrease the utility of that tool when you limit
it''s idioms.
How much Python code would these different proposals break?




很多。我跑了这个:



A lot. I ran this:


find /usr/lib/python2.3/ -name" * .py" -exec grep" def。* = \ [\]" {} \; | wc


查看标准库中的67个实例。将该值乘以1000,10000或更多的因子来反映该字段中的代码,您可能会开始理解更改语言定义的重要性。


-

Troy Melhase, tr**@gci.net

-

我已经在上帝的祭坛上发誓永远敌视各种形式的人类头脑中的暴政。 - 托马斯杰斐逊
find /usr/lib/python2.3/ -name "*.py" -exec grep "def.*=\[\]" {} \; | wc

And see 67 instances just in the standard library. Multiply that by a factor
of 1000, 10000 or more to reflect code in the field, and you might start to
understand the significance of changing the language definition.

--
Troy Melhase, tr**@gci.net
--
I have sworn upon the altar of God eternal hostility against every form of
tyranny over the mind of man. - Thomas Jefferson


这篇关于可变的默认参数问题[Prothon]的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆