Billjk
Billjk

Reputation: 10686

attr_reader in Python

Is there a "synonym" for attr_readerin python, like something that doesn't have to make me type out?:

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 a one line thing that makes self.foo = foo, etc., sort of like how ruby's attr_reader would make

@foo = foo

Upvotes: 7

Views: 2849

Answers (4)

kindall
kindall

Reputation: 184270

What you want to do can be done entirely with positional args 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 your spams in the arglist because Python doesn't like having more than one argument with the same name.)

Note that all locals will be made into attributes on the instance. This can be convenient if you want to initialize a bunch of attributes statically, since you won'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'll want to exclude that variable from the update, or more likely just del self.kwargs afterward.

Upvotes: 1

Macke
Macke

Reputation: 25690

To set 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)

Upvotes: 5

luke14free
luke14free

Reputation: 2539

You can use setattr to set self attr from 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!!'

Upvotes: 1

Intra
Intra

Reputation: 2109

You can do this with kwargs:

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

And you pass in named arguments:

foo = Foo(foo='bar')

Of course, you might want to catch KeyError exception

Upvotes: 1

Related Questions