Attr_reader in Python

Is there a "synonym" for attr_reader

in python, for example, something I don't need to call ?:

class Foo():
    def __init__(self, foo, bar, spam, spammity, spam, spam, quux, foobar, barfoo):
        self.foo = foo
        self.bar = bar
        self.spam = spam
        # And so on...

      

Just one line that does self.foo = foo, etc.

, sort of like ruby attr_reader

make

@foo = foo

      

+3


source to share


4 answers


You can do it with kwargs:

class Foo():
  def __init__(self, **kwargs):
    self.foo = kwargs['foo']

      

And you are passing named arguments:



foo = Foo(foo='bar')

      

Of course you may want to throw a KeyError exception

+1


source


To install everything try:

class Foo():
  def __init__(self, **kwargs):
    for k,v in kwargs.items():
        setattr(self, k, v)

      

Or just some attributes:

class Foo():
  def __init__(self, **kwargs):
    for k in ['foo', 'bar', 'spam']:
        setattr(self, k, kwargs[k])

      



Or from (some) ctor args:

class Foo():
  def __init__(self, foo, bar, spam, bork, kevork):
    for k in ['foo', 'bar']:
        setattr(self, k, locals()[k])

      

Or all of them:

class Foo():
  def __init__(self, foo, bar, spam, bork, kevork):
    args = dict(locals())
    for k, v in (k,v for k,v in args.items() if not k == 'self'):
        setattr(self, k, v)

      

+3


source


You can use setattr to set self attr from a keyword named args.

>>> class Foo():
...     def __init__(self, **kwargs):
...         for attr_name in kwargs.keys():
...             setattr(self,attr_name,kwargs[attr_name])
... 
>>> j=Foo(it_works='cool!!')
>>> j.it_works
'cool!!'

      

+1


source


What you want to do can be done entirely with positional arguments using locals()

:

class Foo():
   def __init__(self, foo, bar, spam, spammity, spaam, 
                spamm, quux, foobar, barfoo):
       self.__dict__.update(locals())

f = Foo(1, 2, 3, 4, 5, 6, 7, 8, 9)
print f.spamm   # 6

      

(I changed two of spam

mine in arglist because Python doesn't like having more than one argument with the same name.)

Please note that all locales will be included in the instance attributes. This can be useful if you want to statically initialize attribute bindings, since you don't need to type self

in front of them:

class Foo():
   def __init__(self, foo, bar, spam, spammity, spaam, 
                spamm, quux, foobar, barfoo):
       a = b = c = 0
       self.__dict__.update(locals())   # sets a, b, and c too

      

However, if you accept keyword arguments, you will want to exclude that variable from the update, or most likely just del self.kwargs

after that.

+1


source







All Articles