Reputation: 17157
Say i am using a class from some python package that looks like the following
class foo(object):
def __init__(self):
self.a = None
self.b = None
self.c = None
self.d = None
self.e = None
self.f = None
Now I need to use attributes b
, d
, and e
of object foobar of class foo in some operation, say call a function qux for instance:
print qux(foobar.b, foobar.d, foobar.e)
Is there any way to create a shorthand version of this, something like the following imagined code:
print qux(*foobar.[b,d,e])
Note the constraints: neither the class nor the function can be changed.
Upvotes: 3
Views: 3592
Reputation: 127340
Since you can't modify the class, how about a function that takes an instance and any number of attribute names, and returns a tuple:
class Foo(object):
def __init__(self):
self.a = 1
self.b = 2
self.c = 3
def getitems(obj, *items):
values = []
for item in items:
values.append(getattr(obj, item))
return tuple(values)
f = Foo()
print getitems(f, 'a', 'c') # prints (1, 3)
qux(*getitems(f, 'a', 'c'))
If you are willing to modify the class, you can override __getitem__
to accept a tuple of keys.
class Foo(object):
def __init__(self):
self.a = 1
self.b = 2
self.c = 3
def __getitem__(self, item):
if isinstance(item, basestring):
# treat single key as list of length one
item = [item]
values = []
for key in item:
# iterate through all keys in item
values.append(getattr(self, key))
return tuple(values)
f = Foo()
print f['a', 'c'] # prints (1, 3)
qux(*f['a', 'c'])
Upvotes: 1
Reputation: 5732
Well, getattr
and setattr
get you close:
Assignment with setattr
(not needed for the next to work, just here for illustration):
class foo(object):
def __init__(self):
for name in 'abcdef':
setattr(self, name, None)
Using values with getattr
:
print qux(*(getattr(foobar, name) for name in 'bde'))
With normal, longer names you'd need to do in ['foo', 'bar']
instead.
Upvotes: 3