setattr与kwargs,pythonic或不?

Imr*_*ran 18 python initialization

__init__()在一些具有许多参数(最多20个)的SQLAlchemy ORM类中使用这样的东西.

def __init__(self, **kwargs):
    for k, v in kwargs.iteritems():
        setattr(self, k, v)
Run Code Online (Sandbox Code Playgroud)

设置这样的属性是"pythonic"吗?

S.L*_*ott 25

是.另一种方法是.

def __init__(self, **kwargs):
    self.__dict__.update( kwargs )
Run Code Online (Sandbox Code Playgroud)

  • 这个比问题中的版本短,但请记住,它不适用于属性(或其他描述符)的属性. (6认同)

dbr*_*dbr 8

是的,如果没有"更好"的方式提供论据.

例如,使用你提到的ORM类,也许允许更多Python.

col = Varchar()
col.index = True
col.length = 255
Run Code Online (Sandbox Code Playgroud)

..而不是..

col = Varchar(index = True, length = 255)
Run Code Online (Sandbox Code Playgroud)

好吧,这不是最好的例子,因为这个**kwargs方法实际上会更好..但我的观点是你应该总是考虑实现某些事情的替代方法,然后再使用有时令人沮丧的事情**kwargs.

另外要记住的是,您可能会丢失用户期望的行为,例如,如果用户提供了无效的关键字arg,则会引发TypeError,这可能会像...一样解决.

def __init__(self, **kwargs):
    valid_kwargs = ['x', 'y', 'z']
    for k, v in kwargs.iteritems():
        if k not in valid_kwargs:
            raise TypeError("Invalid keyword argument %s" % k)
        setattr(self, k, v)
Run Code Online (Sandbox Code Playgroud)

最后要考虑的事情是:

class Hmm:
    def __init__(self, **kwargs):
        for k, v in kwargs.iteritems():
            setattr(self, k, v)
    def mymethod(self):
        print "mymethod should print this message.."

x = Hmm(mymethod = None)
x.mymethod() # raises TypeError: 'NoneType' object is not callable
Run Code Online (Sandbox Code Playgroud)