【发布时间】:2021-09-08 22:11:20
【问题描述】:
class Cls:
def __init__(self, *args, **kwargs):
self.x = *args, **kwargs
@property
def x(self):
return self._x
@x.setter
def x(self, *args, **kwargs):
self._x = do_thing(args, kwargs)
pass
obj = Cls(5, 4, a=15, b=20)
我想将参数传递给 setter,但 self.x = *args, **kwargs 行导致语法错误。不带星号传递意味着元组和字典被传递到 setter 中的 args 中,这不是我想要的。我还尝试将 x 视为一个函数,例如 self.x(*args, **kwargs) 或 self.x.setter(*args, **kwargs),但改为调用 getter,引发 AttributeError,因为变量 self._x 尚不存在。
我正在使用的解决方法是让前两个参数接受元组和字典而不是 *args、**kwargs,但有更好的方法吗?
编辑:因为你们中的一些人想要更多的上下文
该属性是一种图像格式(灰色、rgb、hsv等)。对于setter,我不需要传递特定的图像格式,所以我允许将任何格式传递给kwargs,setter然后将转换并保存到变量中。
【问题讨论】:
-
这没有任何意义。你为什么要这么做?
-
*args, **kwargs正在做的是将列表和字典中的项目和键以有利于将参数和关键字参数传递给函数的格式分离。所以,基本上你想要做的是self._x = argsitem1, argsitem2, kwargsitem1="something", kwargsitem2="somethingelse",这是无效的语法。此外,除非您使用数组(列表或元组,甚至字典)来存储,否则您不能将列表和字典同时存储在变量中。 -
属性设置器定义了当您执行
obj.x = whatever时会发生什么。看起来您并没有试图定义当您执行obj.x = whatever时会发生什么。看起来您正在尝试实现其他目标,并且您错误地决定使用二传手作为实现目标的方式。通过定义这个 setter,你想达到什么基本目标? -
"该属性是图像格式(灰色、rgb、hsv等)对于setter,我不要求传递特定的图像格式,所以我允许传递任何格式到 kwargs,然后 setter 将其转换并保存到变量中。” - 听起来你不需要
*args或**kwargs。 -
属性实现了一个特定的接口,你不能修改。