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
bar
at 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
for
loop instead of two list comprehensions - the time taken in the iteration usingfor
itself 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 ofFoo
automatically in for-loop iterations)Now, if you want to get it really interesting, let's suppose your
Foo
class, 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
metaclass
research - 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 theFoo
class 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: