Reputation: 5449
I am probably approaching this wrong, but would appreciate being straightened out.
I would like to be able to use both the values and the names of some attributes of a class
Sample:
class DoStuff(object):
def __init__(self):
self.a="Alpha"
self.b="Beta"
self.c="Gamma"
def printStuff(self):
for thing in [self.a, self.b, self.c]:
print NAMEOFTHING, thing
What I want is:
a Alpha b Beta c Gamma
How can I get that?
Edit: Some confusion because my example showed me printing ALL the values. Instead I want this:
a Alpha c Gamma
with the list for my print method just having 'a' and 'c' in it.
Upvotes: 3
Views: 104
Reputation: 208465
The way your class and for
loop are set up, there is nothing you can put in place of NAMEOFTHING
to get to the names of those variables. Here are a few alternatives on how you can modify your approach:
Use a dictionary instead of individual attributes, and then provide a list of keys in your for
loop:
class DoStuff(object):
def __init__(self):
self.names = {"a": "Alpha",
"b": "Beta",
"c": "Gamma"}
def printStuff(self):
for name in ['a', 'b', 'c']:
print name, self.names[name]
Use the attribute names in your list and then use getattr()
:
class DoStuff(object):
def __init__(self):
self.a="Alpha"
self.b="Beta"
self.c="Gamma"
def printStuff(self):
for name in ['a', 'b', 'c']:
print name, getattr(self, name)
Upvotes: 8
Reputation: 1321
Following on Jon's answer, you might also find it helpful to set the list of attributes you want to include in the output as an optional argument:
def printStuff(self, included=['a', 'c']):
for thing in included:
print thing, getattr(self, thing)
which makes it easy to generate both outputs, by saying DoStuff().printStuff()
to get just the values of a
and c
, or DoStuff().printStuff(['a', 'b', 'c'])
to get all three. Of course, this allows for varying output—if it's an explicit design-goal that the set of fields being printed is invariant, this would be counterproductive.
Upvotes: 1
Reputation: 896
# You can use __dict__
>>> class x:
>>> def __init__(self):
>>> self.a = 1
>>> self.b = 2
>>> self.c = 3
>>> self.d = 4
>>> def prnt(self):
>>> limit = "b", "c"
>>> return {k:v for (k, v) in self.__dict__.iteritems()if k in limit}
>>> r = x()
>>> print r.prnt()
{'b': 2, 'c': 3}
# __dict__ can be also done outside the class
limit = "b", "c"
print {k:v for (k, v) in r.__dict__.iteritems()if k in limit}
Upvotes: 0
Reputation: 142136
The closest you could get is:
for thing in ['a', 'b', 'c']:
print thing, getattr(self, thing)
Variables can have multiple names and aren't aware of their own name, so if you know it's 'a', then you can use getattr
to resolve the lookup.
Another option (although not greatly different than above)
to_get = ['a', 'b', 'c']
from operator import attrgetter
blah = zip(to_get, attrgetter(*to_get)(self))
Upvotes: 5