gpt4 book ai didi

python - 利用函数参数的一次性绑定(bind)是个坏主意吗?

转载 作者:太空宇宙 更新时间:2023-11-03 13:47:31 24 4
gpt4 key购买 nike

新的 python 用户经常被可变参数默认值绊倒。有意使用此“功能”的陷阱和其他问题是什么,例如,在运行时获得可调整的默认值,这些默认值继续通过 help() 在函数签名中正确显示?

class MutableString (str):

def __init__ (self, value):
self.value = value

def __str__ (self):
return self.value

def __repr__ (self):
return "'" + self.value + "'"


defaultAnimal = MutableString('elephant')

def getAnimal (species=defaultAnimal):
'Return the given animal, or the mutable default.'
return species

并在使用中:

>>> help(getAnimal)
getAnimal(species='elephant')
Return the given animal, or the mutable default.
>>> print getAnimal()
elephant
>>> defaultAnimal.value = 'kangaroo'
>>> help(getAnimal)
getAnimal(species='kangaroo')
Return the given animal, or the mutable default.
>>> print getAnimal()
kangaroo

最佳答案

首先,阅读Why are default values shared between objects .这并没有回答您的问题,但它提供了一些背景知识。


此功能有不同的有效用途,但它们几乎都有一些共同点:默认值是透明、简单、明显可变的内置类型。 Memoization 缓存、递归调用的累加器、可选的输出变量等看起来都是这样的。因此,经验丰富的 Python 开发人员通常会发现其中一种用例——如果他们看到 memocache={}accum=[],他们就会知道会发生什么。但是您的代码看起来根本不像是对可变默认值的使用,这对专家和新手都会产生误导。


另一个问题是你的函数看起来像是在返回一个字符串,但它在说谎:

>>> print getAnimal()
kangaroo
>>> print getAnimal()[0]
e

当然,这里的问题是你错误地实现了 MutableString,并不是说它不可能实现......但是,这仍然应该说明为什么试图“欺骗”解释器并且你的用户倾向于打开意外错误的大门。

--

处理它的明显方法是将更改的默认值存储在模块、函数或(如果它是方法)实例属性中,并使用 None 作为默认值。或者,如果 None 是有效值,则使用其他标记:

defaultAnimal = 'elephant'
def getAnimal (species=None):
if species is None:
return defaultAnimal
return species

请注意,这几乎正是 FAQ 所建议的。即使你天生就有一个可变的值(value),你也应该跳这个舞来绕过这个问题。因此,您绝对不应该从一个固有的不可变值中创建一个可变值来制造问题。

是的,这意味着 help(getAnimal) 不显示当前默认值。但没有人会期望它。

当然,他们可能希望您告诉他们默认值是一个钩子(Hook),但这是文档字符串的工作:

defaultAnimal = 'elephant'
def getAnimal (species=None):
"""getAnimal([species]) -> species

If the optional species parameter is left off, a default animal will be
returned. Normally this is 'elephant', but this can be configured by setting
foo.defaultAnimal to another value.
"""
if species is None:
return defaultAnimal
return species

关于python - 利用函数参数的一次性绑定(bind)是个坏主意吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16618808/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com