【发布时间】:2018-09-15 20:41:57
【问题描述】:
我有一个有点复杂的类Thing,和一个相关的mixin IterMixin(使类可迭代)......以及代码库中其他地方的funky 方法,它接收我的类的实例作为参数.
事实上,我试图将一堆参数捆绑为单个对象,以传递给 多个 外部函数,而不是下面的funky 函数。各种参数对象设计模式...
class IterMixin():
def __iter__(self):
for attr, value in self.__dict__.items():
yield attr, value
class Thing(IterMixin):
def __iter__(self, foo=None, bar=None, baz=999):
if foo is None:
self.foo = {}
else:
self.foo = foo
if bar is None:
self.foo = {}
else:
self.bar = bar
self.baz = baz
@property
def foo(self):
return self._foo
@foo.setter
def foo(self, data)
self._foo = self.parser(data)
@property
def bar(self):
return self._bar
@bar.setter
def bar(self, more_data)
self._bar, self.baz = self.another_parser(more_data)
def parser(self, data):
...do stuff...
return foo
def another_parser(self, more_data):
...do add'l stuff...
return bar, baz
关于funky函数,在一个完全不同的模块中,通过Thing类,我想将Thing的属性(foo、bar和baz)传递给funky 函数作为一个参数...就像这样:
thing_args = Thing()
def funky(*thing_args):
...do stuff...
...expecting to manipulate keys from things_arg
...
return whatever
问题:
如果我不为属性foo 和bar private(例如,通过self._foo)设置setters--即顺便说一句一个下划线 - 然后我在类初始化期间唤起无限递归......因为__init__和这些属性的设置器一遍又一遍地循环并反复调用自己。为避免这种情况,我使用了@property 装饰器,并在设置它们时“私有化”了 foo 和 bar。
但是,当我传递 Thing 类的实例,并通过 splat 或星号将其属性解压缩为 funky 函数中的 args 时,如果我自省这些属性的结果键,我仍然会得到 @987654341 @ 和 _bar。我似乎无法摆脱下划线。 (换句话说,我得到了Thing 的“私有化”属性名称。)
funky 的 biz 逻辑需要解压后的值不能有任何下划线。
为什么会发生这种情况(拆包时的下划线)?我怎样才能解决这个问题?有没有更优雅的方法来初始化 foo 和 bar 属性而不私有化任何东西?或者也许是一种更 Pythonic 的方式来将 Thing 类中的所有属性传递给我的 funky 函数?
【问题讨论】:
-
我觉得你真的是想太多了……不过看起来你玩得很开心,所以我不会抱怨。
-
你为什么不直接传递“东西”?并使用它的属性?
-
如果你想传递一个实例,就好像它是一个属性序列,为什么不把它变成一个序列,或者至少是一个可迭代的?有关示例,请参见 stdlib 中的
namedtuple(尽管您不需要构建任何复杂的东西)。 -
同时,如果您正在寻找如何隐藏私有属性,即使是确定的内省,您只是使用了错误的语言。 Python“私有”只是意味着“按约定私有”。
-
你是说
Thing类的instances的属性吧?
标签: python function class properties setter