【问题标题】:Pass a list or variable number of arguments as method parameters传递一个列表或可变数量的参数作为方法参数
【发布时间】:2018-10-28 12:37:43
【问题描述】:

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

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

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)

那么,最好的实现是什么?我是否走在正确的轨道上?

【问题讨论】:

  • 我不认为这是你想要的,但如果你在你传递的列表之前放一个 * (即:ds1 = Dataset(*[4,3,5])),列表将被解包,它将是就像您输入的一样:ds1 = Dataset(4,3,5)。由于您已经接受 *args 作为参数,这就是您要做的所有事情。如果这是您想要的,请告诉我,以便我可以将其作为答案供其他访问者查看。
  • 接受要么列表可变参数。不要两者都做。
  • @Aran-Fey 你能解释一下原因吗?
  • @DennisPatterson 很好的答案,但对于这种特殊情况,我认为 progmatico 的解决方案最能回答我的问题;3
  • @KamenHristov 因为它引入了歧义。如果你的函数被称为func([1, 2]),你怎么知道是func(1, 2)还是func([[1, 2]])

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


【解决方案1】:

你可以试试这个,

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 的元组和字典并且还想要列表?将“可变参数”构建为列表元素怎么样?

你要求一个列表或可变数量的参数,但列表本身也有一个“可变数量的参数”。

所以使用其中一个。如果您继续最初的想法,请至少像这个答案一样保持简单。

【讨论】:

  • 正是我想要的!但是,如果您(或其他人)能详细说明这是否是完成此任务的最常见方法,我将非常感激,例如,这在专业环境中是否被认为是一种好方法,还是不太可能?跨度>
  • 我编辑了我的答案@KamenHristov,可能很符合要求,但要求在 Python 中不是一个好的要求。
  • 感谢您的回复,您提供的只是我正在寻找的信息类型!肯定会研究 functools.singledispatch 并尝试使我的代码尽可能明确。
猜你喜欢
  • 2023-04-09
  • 1970-01-01
  • 2013-12-25
  • 2011-04-01
  • 2014-03-08
相关资源
最近更新 更多