Pythonic way to assign a parameter to an attribute?

Code examples are as follows:

def assign(self, input=None, output=None, param=None, p1=None, p2=None):
    if input:
        self.input = input
    if output:
        self.output = output
    if param:
        self.param = param
    if p1:
        self.p1 = p1
    if p2:
        self.p2 = p2

Although this looks very clear, it suffers if there are 10 parameters for this function. Anyone have any ideas on a more convenient way to do this?

+5
source share
4 answers

you can do something like:

def assign(self,**kwargs):
    for k,v in kwargs.items():
        if v:
           setattr(self,k,v)

It is quite simple and suitable for many situations. If you want to save a set of keywords that you accept and raise a TypeError for the rest:

#python2.7 and newer
def assign(self,allowed_kwargs={'foo','bar','baz'},**kwargs):
    if kwargs.keysview() - allowed_kwargs:
        raise TypeError('useful message here...')
    for k in allowed_kwargs:
        setattr(self,k,kwargs[k])

This checks somewhat, since the user will see a set of allowed kwargs.

+7
source

Explicit is better than implicit

def assign(self, input=None, output=None, param=None, p1=None, p2=None):

has many advantages over

def assign(self, **kwargs)
  • This is self-documenting.
  • Useful TypeErroroccurs if an invalid parameter is passed assign.
  • assign ,

, , OP, , if . , - :

class Foo(object):
    def assign(self, input=None, output=None, param=None, p1=None, p2=None):
        for name in 'input output param p1 p2'.split():
            val = vars()[name]
            if val is not None:
                setattr(self, name, val)

foo = Foo()
foo.assign(p1=123, p2='abc')
+1

python . :

>>> def assign(self, input=None, output=None, param=None, p1=None, p2=None):
...     pass
... 

, :

>>> help(assign)
Python Library Documentation: function assign in module __main__

assign(self, input=None, output=None, param=None, p1=None, p2=None)

:

>>> def assign2(self, **kwargs):
...     pass
... 

:

>>> help(assign2)
Python Library Documentation: function assign2 in module __main__

assign2(self, **kwargs)

, , . ( ​​ ).

- ? , , , . ; python !

>>> import collections
>>> Assignment = collections.namedtuple('Assignment', 'input output param p1 p2')
>>> assign = Assignment(None, None, None, None, None)._replace
>>> assign(p1=10)
Assignment(input=None, output=None, param=None, p1=10, p2=None)
>>> help(Assignment)
Python Library Documentation: class Assignment in module __main__

class Assignment(__builtin__.tuple)
 |  Assignment(input, output, param, p1, p2)
 |  
... SNIP

namedtuple , , . , , , , ; . ; , :

>>> class Assignable(object):
...     def assign(self, input=None, output=None, param=None, p1=None, p2=None):
...         _kwargs = vars()
...         _kwargs.pop('self')
...         vars(self).update((attr, value) for attr, value in _kwargs.items() if value is not None)
... 
>>> a = Assignable()
>>> vars(a)
{}
>>> a.assign(p1=6)
>>> vars(a)
{'p1': 6}
>>> a.p1
6

help() - !

>>> help(a.assign)
Python Library Documentation: method assign in module __main__

assign(self, input=None, output=None, param=None, p1=None, p2=None) method of __main__.Assignable instance
0

mgilson unutbu .

:

class Buu(object):
    def assign(self,
               input=None, output=None,
               param=None,
               p1=None, p2=None,
               **kw):
        for k,v in locals().iteritems():
            if v not in (self,None,kw):
                if v == (None,):
                    setattr(self,k,None)
                else:
                    setattr(self,k,v)
        for k,v in kw.iteritems():
            setattr(self,k,v)

buu = Buu()

buu.assign(None,(None,), p1=[])
print "buu attributes:",vars(buu)
print

buu.assign(1,p2 = 555, xx = 'extra')
print "buu attributes:",vars(buu)

buu attributes: {'output': None, 'p1': []}

buu attributes: {'p2': 555, 'output': None, 'xx': 'extra', 'p1': [], 'input': 1}

, None , , , , None , .
, None .
, , None, (None,).

- (None,)??? ?
, !

0

All Articles