将模块常量用作Python中的默认函数参数可以吗? [英] Is it ok to use module constants as default function arguments in Python?

查看:58
本文介绍了将模块常量用作Python中的默认函数参数可以吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

基本上是这样的:

DEFAULT_TIMEOUT = 10
# or even: from my_settings import DEFAULT_TIMEOUT

def get_google(timeout=DEFAULT_TIMEOUT):
    return requests.get('google.com', timeout=timeout)

我认为只要常量真正保持不变,它就可以正常工作.但是我有时会看到这样的模式:

I would assume that as long as the constant really stays constant this should work just fine. Yet I sometimes see a pattern like this:

DEFAULT_TIMEOUT = 10

def get_google(timeout=None):
    if timeout is None:
        timeout = DEFAULT_TIMEOUT
    return requests.get('google.com', timeout=timeout)

这些等效吗?还是我应该优先选择另一个?

Are these equivalent or should I prefer one over the other?

推荐答案

使用常量"作为默认值没有问题.正如您所说,只要常数"确实是常数,就没有关系.唯一的事情是您必须确保在函数之前定义了常量,但是通常人们将所有常量都放在文件的顶部,所以这不是问题.

There's no problem with using the "constant" as a default value. As you say, as long as the "constant" is really constant, it won't matter. The only thing is that you do have to make sure the constant is defined before the function, but usually people put all their constants at the top of the file so that's not an issue.

当所需的默认值是可变值(例如列表)时,您描述的第二种模式很常见.您经常会看到这样的事情:

The second pattern you describe is common when the desired default is a mutable value, such as a list. You often see things like this:

def foo(x=None):
    if x is None:
        x = []

而不是 def foo(x = []).您会发现很多与此有关的问题,但本质上是因为,如果不这样做,可变的默认值将在多次调用该函数的过程中保持不变,这通常是不希望的.

instead of def foo(x=[]). You can find many questions about this, but essentially it is because if you don't do it this way, the mutable default will persist across multiple calls to the function, which usually isn't desirable.

但是,将这种模式用于可变的模块级常量将无法解决该问题.如果您有:

However, using this pattern for a mutable module-level constant wouldn't fix that problem. If you have:

SOME_CONSTANT = []

def foo(x=None):
    if x is None:
        x = SOME_CONSTANT

...那么您仍然在多个调用中重复使用相同的可变值.(当然,将可变值定义为常量"可能不是一个好主意.)这就是为什么我在注释中询问您是否看到有人专门使用模块常量来做这种事情.

. . . then you're still reusing the same mutable value across multiple calls. (Of course, defining a mutable value as a "constant" is probably not a good idea anyway.) That's why I was asking in the comments if you've seen someone specifically doing this kind of thing with module constants.

如果模块级别的默认值实际上不是常量,而是打算由其他代码更改的值,那么也将使用此None-then-if模式.如果您执行 def foo(x = DEFAULT_TIMEOUT),则 x 的默认值就是您定义时 DEFAULT_TIMEOUT 的值函数.但是,如果您使用None-then-if模式,则默认值为您调用函数时的 DEFAULT_TIMEOUT .一些库定义了模块级别的值,这些值并不是恒定不变的,而是可以在执行过程中更改的配置值.这允许用户执行诸如设置 DEFAULT_TIMEOUT = 20 的操作来更改所有后续调用的默认超时,而不必每次都传递 timeout = 20 .在这种情况下,您需要在函数内部进行if检查,以确保每个调用都使用 DEFAULT_TIMEOUT 的当前"值.

This None-then-if pattern would also be used if the module-level default were actually not a constant, but a value intended to be changed by other code. If you do def foo(x=DEFAULT_TIMEOUT), the default value of x is whatever DEFAULT_TIMEOUT was at the time you defined the function. But if you use the None-then-if pattern, the default will be whatever DEFAULT_TIMEOUT is at the time you call the function. Some libraries define module-level values that aren't meant to be constant, but are rather configuration values that may be changed in the course of execution. This allows users to do things like set DEFAULT_TIMEOUT = 20 to change the default timeout for all subsequent calls, rather than having to pass timeout=20 every time. In this case you would want the if check inside the function, to ensure that every call uses the "current" value of DEFAULT_TIMEOUT.

这篇关于将模块常量用作Python中的默认函数参数可以吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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