参数上的Python __init__ setattr?

mk1*_*k12 5 python parameters initialization list setattr

通常__init__方法似乎与此类似:

def __init__(self, ivar1, ivar2, ivar3):
    self.ivar1 = ivar1
    self.ivar2 = ivar2
    self.ivar3 = ivar3
Run Code Online (Sandbox Code Playgroud)

有没有办法将参数转换为一个列表(不使用*args**kwargs),然后使用setattr设置实例变量,参数名称和参数传递?也许可以对列表进行切片,例如,您需要至少将其切片,[1:]因为您不需要self.self.

(实际上我想它需要是一个字典来保存名称和值)

像这样:

def __init__(self, ivar1, ivar2, ivar3, optional=False):
    for k, v in makedict(self.__class__.__init__.__args__): # made up __args__
        setattr(self, k, v)
Run Code Online (Sandbox Code Playgroud)

谢谢!

回应未知的答案,我发现这个工作:

Class A(object):
    def __init__(self, length, width, x):
        self.__dict__.update(dict([(k, v) for k, v in locals().iteritems() if k != 'self']))
Run Code Online (Sandbox Code Playgroud)

要么

Class A(object):
    def __init__(self, length, width, x):
        self.__dict__.update(locals())
        del self.__dict__['self']
Run Code Online (Sandbox Code Playgroud)

还不错..

Unk*_*own 7

干得好.是的,这是一个丑陋的邪恶黑客.是的,对象需要一个__dict__变量.但是,嘿,它是一个整洁的小内衬!

def __init__(self):
    self.__dict__.update(locals())
Run Code Online (Sandbox Code Playgroud)

构造函数可以使用任何类型的参数.

class test(object):
    def __init__(self, a, b, foo, bar=5)...

a = test(1,2,3)
dir(a)

['__class__', '__delattr__', '__dict__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'a', 'b', 'foo', 'bar', 'self']
Run Code Online (Sandbox Code Playgroud)

它还将包括self,但您可以轻松删除它或创建自己的忽略self的更新功能.

  • 这会将所有局部变量设置为属性,特别是"自我",这有点荒谬.:)你当然可以首先从本地()中过滤掉"自我",但是它已经变得不那么整洁了. (2认同)

Ant*_*sma 6

您可以使用inspect.getargspec并将其封装为装饰器.查找可选和关键字参数有点棘手,但是应该这样做:

def inits_args(func):
    """Initializes object attributes by the initializer signature"""
    argspec = inspect.getargspec(func)
    argnames = argspec.args[1:]
    defaults = dict(zip(argnames[-len(argspec.defaults):], argspec.defaults))
    @functools.wraps(func)
    def __init__(self, *args, **kwargs):
        args_it = iter(args)
        for key in argnames:
            if key in kwargs:
                value = kwargs[key]
            else:
                try:
                    value = args_it.next()
                except StopIteration:
                    value = defaults[key]
            setattr(self, key, value)
        func(self, *args, **kwargs)
    return __init__
Run Code Online (Sandbox Code Playgroud)

然后你可以像这样使用它:

class Foo(object):
    @inits_args
    def __init__(self, spam, eggs=4, ham=5):
        print "Foo(%r, %r, %r)" % (self.spam, self.eggs, self.ham)
Run Code Online (Sandbox Code Playgroud)