### 将函数参数分配给`self`

``````class SomeClass():
def __init__(self, a, b, c):
self.a = a
self.b = b
self.c = c
``````

#### 10 个答案:

``````>>> def assign_attributes(obj, localdict, names):
...     for name in names:
...         setattr(obj, name, localdict[name])
...
>>> class SomeClass():
...     def __init__(self, a, b, c):
...         assign_attributes(self, vars(), ['a', 'b', 'c'])
``````

``````>>>  class C(object):
def __init__(self, **kwargs):
self.__dict__ = dict(kwargs)
``````

``````>>> c = C(a='a', b='b', c='c')
>>> c.a, c.b, c.c
('a', 'b', 'c')
``````

（顺便说一下，这个模式来自Guido他自己的坏自我，作为在Python中定义枚举问题的一般解决方案。创建一个类似上面的类`Enum`，然后你可以编写像{ {1}}，然后使用`Colors = Enum(Red=0, Green=1, Blue=2)``Colors.Red``Colors.Green`。）

``````>>> from collections import namedtuple
>>> SomeClass = namedtuple("SomeClass", "a b c")
>>> sc = SomeClass(1, "x", 200)
>>> print sc
SomeClass(a=1, b='x', c=200)
>>> print sc.a, sc.b, sc.c
1 x 200
``````

@ pcperini的回答：

``````>>> class SomeClass():
def __init__(self, a, b=1, c=2):
for for name,value in vars().iteritems():
if name != 'self':
setattr(self,name,value)

>>> s = SomeClass(7,8)
>>> print s.a,s.b,s.c
7 8 2
``````

``````>>> class Test:
...     def __init__(self, a, b, c):
...         l = locals()
...         for key in l:
...             self.__dict__[key] = l[key]
...
>>> t = Test(1, 2, 3)
>>> t.a
1
>>>
``````

``````>>> class SomeClass():
@ArgsToSelf
def __init__(a, b=1, c=2, d=4, e=5):
pass

>>> s=SomeClass(6,b=7,d=8)
>>> print s.a,s.b,s.c,s.d,s.e
6 7 2 8 5
``````

``````>>> import inspect
>>> def ArgsToSelf(f):
def act(self, *args, **kwargs):
arg_names,_,_,defaults = inspect.getargspec(f)
defaults=list(defaults)
for arg in args:
setattr(self, arg_names.pop(0),arg)
for arg_name,arg in kwargs.iteritems():
setattr(self, arg_name,arg)
defaults.pop(arg_names.index(arg_name))
arg_names.remove(arg_name)
for arg_name,arg in zip(arg_names,defaults):
setattr(self, arg_name,arg)
return f(*args, **kwargs)
return act
``````

``````class Point(Bunch):
x = 0
y = 0

p0 = Point()
assert p0.x == 0
assert p0.y == 0

p1 = Point(x=10, y=20)
assert p1.x == 10
assert p1.y == 20
``````

`[setattr(self, key, value) for key, value in kwargs.items()]`

``````  kwargs = { 'd':1, 'e': 2, 'z': 3, }

class P():
def __init__(self, **kwargs):
[setattr(self, key, value) for key, value in kwargs.items()]

x = P(**kwargs)
dir(x)
['__doc__', '__init__', '__module__', 'd', 'e', 'z']
``````

## 解决方案

``````class SomeClass():
def __init__(self, a, b, c):
vars(self).update(dict((k,v) for k,v in vars().iteritems() if (k != 'self')))

sc = SomeClass(1, 2, 3)
# sc.a == 1
# sc.b == 2
# sc.c == 3
``````

@ user3638162答案的一个问题是`locals()`包含'self'变量。因此，您最终得到了额外的`self.self`。如果一个人不介意额外的自我，那么解决方案可以简单地

``````class X:
def __init__(self, a, b, c):
self.__dict__.update(locals())

x = X(1, 2, 3)
print(x.a, x.__dict__)
``````

`self`

``````class X:
def __init__(self, a, b, c):
self.__dict__.update(l for l in locals().items() if l[0] != 'self')

x = X(1, 2, 3)
print(x.a, x.__dict__)
``````