gpt4 book ai didi

python - 为什么在 Python 中不允许使用 foo(*arg, x)?

转载 作者:IT老高 更新时间:2023-10-28 22:12:41 25 4
gpt4 key购买 nike

看下面的例子

point = (1, 2)
size = (2, 3)
color = 'red'

class Rect(object):
def __init__(self, x, y, width, height, color):
pass

打电话会很诱人:

Rect(*point, *size, color)

可能的解决方法是:

Rect(point[0], point[1], size[0], size[1], color)

Rect(*(point + size), color=color)

Rect(*(point + size + (color,)))

但是为什么 Rect(*point, *size, color) 是不允许的,你能想到任何语义歧义或普遍的缺点吗?

编辑:具体问题

为什么函数调用中不允许有多个 *arg 扩展?

为什么 *arg 扩展后不允许位置参数?

最佳答案

我不会谈论为什么多元组解包不是 Python 的一部分,但我会指出您没有将您的类与您的示例中的数据相匹配。

你有以下代码:

point = (1, 2)
size = (2, 3)
color = 'red'

class Rect(object):
def __init__(self, x, y, width, height, color):
self.x = x
self.y = y
self.width = width
self.height = height
self.color = color

但表达 Rect 对象的更好方法如下:

class Rect:
def __init__(self, point, size, color):
self.point = point
self.size = size
self.color = color

r = Rect(point, size, color)

一般来说,如果您的数据在元组中,请让您的构造函数采用元组。如果您的数据在字典中,请让您的构造函数使用字典。如果你的数据是一个对象,让你的构造函数获取一个对象,等等。

一般来说,您希望使用该语言的惯用语,而不是试图绕过它们。


编辑看到这个问题有多受欢迎,我给你一个装饰器,让你可以随心所欲地调用构造函数。

class Pack(object):

def __init__(self, *template):
self.template = template

def __call__(self, f):
def pack(*args):
args = list(args)
for i, tup in enumerate(self.template):
if type(tup) != tuple:
continue
for j, typ in enumerate(tup):
if type(args[i+j]) != typ:
break
else:
args[i:i+j+1] = [tuple(args[i:i+j+1])]
f(*args)
return pack


class Rect:
@Pack(object, (int, int), (int, int), str)
def __init__(self, point, size, color):
self.point = point
self.size = size
self.color = color

现在你可以用任何你喜欢的方式初始化你的对象了。

r1 = Rect(point, size, color)
r2 = Rect((1,2), size, color)
r3 = Rect(1, 2, size, color)
r4 = Rect((1, 2), 2, 3, color)
r5 = Rect(1, 2, 2, 3, color)

虽然我不建议在实践中使用它(它违反了你应该只有一种方法来做这件事的原则),但它确实证明了在 Python 中通常有一种方法可以做任何事情。

关于python - 为什么在 Python 中不允许使用 foo(*arg, x)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6387631/

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