Assume I have a simple class like
class Foo:
def __init__(bar):
self.x = transform1(bar)
self.y = transform2(bar)
I'm now interested in generating a class, where I can pass an iterable for bar to the initializer and get back an instance of Foo where i can access the members x and y like iterables of the size of bar, i.e.
x = [1, 2, 3]
foo = Foo(x)
plt.plot(foo.x, foo.y)
I know one could easily do
foo = [Foo(elem) for elem in x]
plt.plot([elem.x for elem in foo], [elem.y for elem in foo])
but this feels verbose and probably is not very efficient. I can roughly imagine a solution with numpy structured arrays, but I'm just curious if there are any standard solutions to this. Perhaps using metaclasses. Googling mostly came up with results for how to get a list of all the members of a class or similar.
If one could even come up with a solution that allows for indexing either the object foo or its members, this would be grand.
If I get this right, you just want to transform all elements in
barat once. just do it, instead of one scalar at a time. Just do it:It is really that simple. There are fancy things if you'd want to run transform1 and transform2 in parallel, using threads or processes, or if you'd like to have all the transforms calculated just as needed, in a lazy way.
But for plotting your graph, a list will do. And there are even no gains in doing it in a single
forloop instead of two list comprehensions - the time taken in the iteration usingforitself is negligible.If you want to be able to index the instance itself, and get back objects that have the needed attributes, what is necessary is to write a class with the
__getitem__method - and have the objects returned by getitem to have both attributes.For that you could use a simpler class, representing your scalar, and depending on what you need, this simpler class can be a namedtuple:
(The
__len__method, combined with the__getitem__allows Python to use instances ofFooautomatically in for-loop iterations)Now, if you want to get it really interesting, let's suppose your
Fooclass, with the scalar application of the transforms exists as in your question - it is possible to "transform" it so that it can operate with sequences.Than we get closer to the original
metaclassresearch - and can be achieved by using a class decorator. Class decorators were introduced a long while back to replace some of the uses of metaclasses.And here is how this behaves in the interactive interpreter:
The "factory" function above could be made into a
__new__and inserted into the decorated class, and then the resulting decorated class would behave as the real class - but specially if you have introspecting code and need theFooclass to be real class operating on scalars, you'd better have two separate classes at all - one creating the sequences, the other dealing with scalars.In that case you could ust strip the "factory" function, have "autosequence" to return the AutoSequence class itself, and use it like this: