I have the following (obviously simplified) class
class A(object)
def __init__(self, a):
self.a = a
self.b = 'b'
# Other class attributes are added
class B(list):
"""
Some customization of this class...
"""
pass
BB = B([A(i) for i in range(10)])
I want to do
B.a
and get a list of all the a attributes from every contained item in B. I know in order to do this, I need to overwrite __getattr__, but I’m not sure the best way to implement this. This needs to be generic as B doesn’t know any of the attributes of A that may need to be accessed.
Can someone offer some advice on the implementation of this idea?
General Solution:
If you wish for this to work across the board, then you can override
__getattr__()as you thought:Giving us:
Note that
__getattr__()only gets called if the attribute doesn’t already exist. So, if you setbb.bto another value, you will get that instead:Gives us:
Example to show the lack of need for
Bto know about it’s contents:Original Answer:
The easiest way to do this is with a generator expression.
This generator expression is the equivalent of:
I also used the
property()builtin as a decorator to makeB.aact as an attribute rather than a function.We can then do:
and get:
You could use a list comprehension ([item.a for item in self]) if you definitely wanted a list rather than an iterator, but generally the iterator is more useful, and can be easily made into a list (as shown above).
Note you could also do this even more simply by assigning the generator expression:
However, this means the generator will be exhausted after the first use, so I would advise against it.