python函数使用多个默认值或根本没有默认值

Posted

技术标签:

【中文标题】python函数使用多个默认值或根本没有默认值【英文标题】:python function use multiple defaults or no defaults at all 【发布时间】:2013-07-23 07:45:38 【问题描述】:

我正在定义一个代表向量的类:

'''
An entity with size and direction
'''
UNINITIALIZED = -1

class myVector():    
    def __init__(self,direction = UNINITIALIZED,size = UNINITIALIZED):
        self.direction = direction
        self.size = size

对于使用该类,我设想了 2 个场景:要么我知道向量在启动时的特性,然后使用这些值启动它:

v = myVector(4,2)

或者我在启动时不知道这些,然后我很高兴它将获得默认值。

但是,通过上述实现,实现了第三种情况 - 仅使用 第一个参数:

v = myVector(4)

在这种情况下,只有第二个参数 (size) 会被赋予默认值,结果对象没有多大意义。

在我看来,所需的行为在这种情况下要么使用两个参数,要么不使用。实现这一点的一种方法是在这种情况下引发异常。

def __init__(self,direction = UNINITIALIZED,size = UNINITIALIZED):
    if (direction != UNINITIALIZED) and (size == UNINITIALIZED):
        raise Exception('Use both parameters or none') 
    self.direction = direction
    self.size = size

你认为优雅地做到这一点的pythonic方式是什么?

【问题讨论】:

【参考方案1】:

大小和方向对我来说就像一个元组:

class myVector():    
    def __init__(self, sd=(UNINITIALIZED, UNINITIALIZED)):
       try:
           self.size, self.direction = sd
       except (ValueError, TypeError) as e:
           raise ValueError('two values of size and direction must be specified')

如果不需要默认值,则使用大小和方向的元组调用它。

如果您不想将语义更改为需要传递一个元组,如果您不使用其他参数,另一种方法是将 sd 更改为 *args 并做同样的事情 - 虽然这对我来说似乎不太明确并且意味着您不能将可选参数用于其他任何事情。

【讨论】:

谢谢!有意义的设计中的一些小改动。 如果使用 *args 语义,则无法分配默认值。我在下面处理了这个案例。【参考方案2】:

你也可以这样定义类:

class myVector():
    def __init__(self,*direction_and_size):
        if not len(direction_and_size):
            direction_and_size = [UNINITIALIZED, UNINITIALIZED]
        assert len(direction_and_size) == 2, "Please provide both parameters"
        self.direction,  self.size = direction_and_size

>>> v = myVector()
>>> v = myVector(4,2)
>>> v = myVector(4)
AssertionError: Please provide both parameters

【讨论】:

感谢 Frodon,声明输入数量的长度也是一个好主意。【参考方案3】:

这样的?

class myVector():
    def __init__(self, direction = -1, size = -1):
        if (-1 in (direction, size)):
            self.size, self.direction = (-1, -1) #do your own fault/error handling here
                                                 #this just makes the example easier
        else:
            self.size = size,
            self.direction = direction

c1 = myVector(1, 1)
c2 = myVector(1)
c3 = myVector()

print(c1.direction, c2.direction, c3.direction)

输出: 1 -1 -1

【讨论】:

感谢 Daan Timmer,我喜欢优雅的降级,它只是将两个值都设置为默认值,以防它们中的任何一个被默认。

以上是关于python函数使用多个默认值或根本没有默认值的主要内容,如果未能解决你的问题,请参考以下文章

函数默认参数和rest

函数默认参数和rest

img src 的三进制,返回值或默认值

Xcode 6 为布局边距设置默认值或禁用它们

未知模板类型的默认值或零值

在传递给Postgres之前使用Postgres默认值或生成它们是更好的做法吗?