将列表或可变数量的参数作为方法参数传递

时间:2018-10-28 12:37:43

标签: python oop variadic-functions setter class-design

我想知道最好的(最Python化的)解决方案是将列表或可变数量的参数传递给函数/方法。

例如,我必须参加以下课程:

class Dataset():
def __init__(self, *args):
    self.data_set = args

这是setter属性的一部分:

@data_set.setter
def data_set(self, args):
    data = []
    for item in args:
        if type(item) is list:
            data = [k for k in item]
            break
        data.append(item)
    self._data_set = data

我在网上搜索,但找不到太多关于该主题的信息。 我的目标是设计类构造函数,使其可以与给定参数的列表一起使用:

  

ds1 =数据集([4,3,5])

或变量号或参数:

  

ds1 =数据集(4,3,5)

那么,什么是最好的实现方式?我在正确的轨道上吗?

1 个答案:

答案 0 :(得分:0)

您可以尝试一下,

class Dataset():
    def __init__(self, *args):
        if isinstance(args[0], list) and len(args) == 1:
            print('Received a list')
        else:
            print('Received:', args)

obj = Dataset(1,2,3)
obj = Dataset([1,2,3], 2)
obj = Dataset([1,2,3])

输出:

Received: (1, 2, 3)                                                       
Received: ([1, 2, 3], 2)                                                  
Received a list 

编辑:

此代码以一种简单的方式实现了您想要的功能。而已。还有其他方法, 在我看来,它们并不简单。

您的评论实际上是一个很好的问题。

问题不在此代码中,而是在您的要求和Python语言中。 您想要方法重载,而Python没有它。

测试参数类型是非Python语言的,因为Python是一种动态类型的语言。您可以做到这一点,但是您只能将函数的使用范围限制为特定类型。

测试参数类型也会产生典型的if..elif链。

如果要编写函数,请查看functools.singledispatch装饰器。 这就消除了代码中的if..elif链。使用它,您可以定义基本功能并为每种类型注册特定的实现。简单易读。但这会路由到基于第一个参数的函数实现。现在,例如方法,由于self而无法使用。您可以change that,但现在看起来不再简单了。

由于Python不直接支持方法/函数重载,因此您要求的不是常用的模式。

现在,Aran Fey给您很好的建议。像这样的编码行为在Python中并不常见,并且实际上引入了歧义。您的API合同不清楚。我应该通过列表还是变量。为什么选择呢?仅仅因为您已经具有带有* args和* kwargs的元组和字典,并且还想要列表?如何将“ varargs”构建为列表元素?

您需要一个列表或可变数量的参数,但是列表本身也具有“可变数量的参数”。

因此使用其中一个。如果您继续使用最初的想法,那么至少要像下面的答案一样简单。