To create a property in a class you simply do self.property = value
. I want to be able to have the properties in this class completely dependent on a parameter. Let us call this class Foo
.
instances of the Foo
class would take a list of tuples:
l = [("first","foo"),("second","bar"),("anything","you get the point")]
bar = Foo(l)
now the instance of the Foo
class we assigned to bar
would have the following properties:
bar.first
#foo
bar.second
#bar
bar.anything
#you get the point
Is this even remotely possible? How?
These are called attributes, rather than properties. With that in mind, the method setattr()
becomes more obvious:
class Foo(object):
def __init__(self, l):
for k, v in l:
setattr(self, k, v)
This takes each key-value pair in l
and sets the attribute k
on the new instance of Foo
(self
) to v
.
Using your example:
l = [("first","foo"),("second","bar"),("anything","you get the point")]
bar = Foo(l)
print bar.first
#foo
print bar.second
#bar
print bar.anything
#you get the point
I thought of another answer you could use using type()
. It's completely different to my current answer so I've added a different answer:
>>> bar = type('Foo', (), dict(l))()
>>> bar.first
'foo'
>>> bar.second
'bar'
>>> bar.anything
'you get the point'
type()
returns a class, not an instance, hence the extra ()
at the end.
There are two ways to do this:
Use setattr
like this. This approach is feasible if you only need to process the initial list once, when the object is constructed.
class Foo:
def __init__(self, l):
for (a, b) in l:
setattr(self, a, b)
Define a custom __getattr__
method. Preferably, you would store the properties in a dict
for faster lookup, but you can also search the original list. This is better if you want to later modify the list and want this to be reflected in the attributes of the object.
class Foo:
def __init__(self, l):
self.l = l
def __getattr__(self, name):
for a in self.l:
if a[0] == name:
return a[1]
return None
Something like this?
>>> class Foo:
... def __init__(self, mylist):
... for k, v in mylist:
... setattr(self, k, v)
...
>>> l = [("first","foo"),("second","bar"),("anything","you get the point")]
>>> bar = Foo(l)
>>> bar.first
'foo'
>>> bar.second
'bar'
>>> bar.anything
'you get the point'
Using setattr
you can do this by passing in the list and just iterating through it.
setattr works.
>>> class Foo:
... def __init__(self,yahoo):
... for k,v in yahoo:
... setattr(self,k,v)
...
>>> l = [("first","foo"),("second","bar"),("anything","you get the point")]
>>> bar = Foo(l)
>>> print bar.first
foo
>>> print bar.second
bar
>>> print bar.anything
you get the point