我想一劳永逸地自动解压缩init变量。我的思维过程是解压缩所有并使用setattr和变量的名称作为属性名称。
class BaseObject(object):
def __init__(self, *args):
for arg in args:
setattr(self, argname, arg)
class Sub(BaseObject):
def __init__(self, argone, argtwo, argthree, argfour):
super(Sub, self).__init__(args*)
然后你应该能够做到:
In [3]: mysubclass = Sub('hi', 'stack', 'overflow', 'peeps')
In [4]: mysubclass.argtwo
Out[4]: 'stack'
基于'stack'的参数被命名为argtwo
。
通过这种方式,您可以自动获得访问权限,但仍然可以覆盖如下:
class Sub(BaseObject):
def __init__(self, argone, argtwo, argthree, argfour):
super(Sub, self).__init__(arglist)
clean_arg_three = process_arg_somehow(argthree)
self.argthree = clean_arg_three
显然,我坚持如何将param的实际名称(argone,argtwo等)作为字符串传递给setattr
,以及如何正确地将args传递给super init
(args
)的super(Sub, self).__init__(args*)
谢谢
答案 0 :(得分:1)
使用kwargs而不是args
class BaseObject(object):
def __init__(self, **kwargs):
for argname, arg in kwargs.iteritems():
setattr(self, argname, arg)
class Sub(BaseObject):
def __init__(self, argone, argtwo, argthree, argfour):
super(Sub, self).__init__(argone=argone, argtwo=argtwo, argthree=argthree)
然后你可以这样做:
s = Sub('a', 'b', 'c')
答案 1 :(得分:1)
import inspect
class BaseObject(object):
def __init__(self, args):
del args['self']
self.__dict__.update(args)
class Sub(BaseObject):
def __init__(self, argone, argtwo, argthree, argfour):
args = inspect.getargvalues(inspect.currentframe()).locals
super(Sub, self).__init__(args)
s = Sub(1, 2, 3, 4)
答案 2 :(得分:1)
Sub.__init__()
需要以某种方式发现BaseObject.__init__()
的参数名称。正如Uri Shalit建议的那样,明确的方法是将参数字典传递给inspect
。或者,您可以使用import inspect
class BaseObject(object):
def __init__(self):
frame = inspect.stack()[1][0]
args, _, _, values = inspect.getargvalues(frame)
for key in args:
setattr(self, key, values[key])
class Sub(BaseObject):
def __init__(self, argone, argtwo, argthree, argfour):
super(Sub, self).__init__()
模块神奇地执行此操作,而子类中不需要额外的代码。这伴随着魔法的通常缺点("如何发生?' d。)。
Sub.__init__()
这样写得很好但是如果你没有定义inspect
,这将从错误的地方(即从你调用Sub()的函数中获取参数来创建一个对象) 。您可以使用__init__()
来重复检查调用者是BaseObject
的子类的set_attributes_from_my_arguments()
函数。或者您可以将此代码移动到单独的方法,例如__init__()
,并从您的子类中调用该方法。当你想要这种行为时,new
方法。