Re: new.instancemethod __iter__
Steven D'Aprano wrote: If you want iterator operations similar to itertools, why does this mean you need to replace anything? Just create your own iterators. Or use pre-processing and post-processing to get what you want. Can you show an example of what you would like to happen? Steven, my classes repesent musical objects. The fundamental paradigm I want to apply is that of a Sequence, i.e. the most abstract aspect of music is that things occur in a certain order. Then I have a TimedSequence class, which is a Sequences whose elements have a time attribute. I now want to be able to append such Sequences by writing s1 = TimedSequence (time=1,'a') # one-element Sequence s2 = TimedSequence (time=2,'b') y = s1*2 + s2 Naively appending those sequences would give me Time=1,'a' Time=1,'a' Time=2,'b' but this is not what I want. Time needs to progress if I append a sequence to another. So what I really want is something like Time=1,'a' Time=2,'a' Time=3,'b' This implies that time is shifted to the next integer, but this is not always the case. I need to know about some kind of alignment. In music this translates to let a sequence start at the beginning of a bar, or half bar or quarter note or whatever. So I want to write y = s1*2 + s2(align=10) which should iterate as Time=1,'a' Time=2,'a' Time=10,'b' I have no difficulty passing align to the object (using __call__) and use it while I furnish my own __iter__() method. However I don't quite see how I can do this with bare itertools, though I may be wrong here. Bare in mind that it is not only about somehow getting the job done. The beauty of the resulting syntax is also important. -- http://mail.python.org/mailman/listinfo/python-list
Re: new.instancemethod __iter__
Christian Heimes wrote: If you *really* need to overwrite __iter__ on your instance rather than defining it on your class, you need to proxy the method call: class MyObject(object): def __iter__(self): return self.myiter() obj = MyObject() obj.myiter = myiter That should do the trick. Thanks a lot, that works. -- http://mail.python.org/mailman/listinfo/python-list
Re: new.instancemethod __iter__
Martin Drautzburg wrote: Steven D'Aprano wrote: If you want iterator operations similar to itertools, why does this mean you need to replace anything? Just create your own iterators. Or use pre-processing and post-processing to get what you want. Can you show an example of what you would like to happen? Steven, my classes repesent musical objects. The fundamental paradigm I want to apply is that of a Sequence, i.e. the most abstract aspect of music is that things occur in a certain order. Then I have a TimedSequence class, which is a Sequences whose elements have a time attribute. I now want to be able to append such Sequences by writing s1 = TimedSequence (time=1,'a') # one-element Sequence s2 = TimedSequence (time=2,'b') y = s1*2 + s2 Naively appending those sequences would give me Time=1,'a' Time=1,'a' Time=2,'b' but this is not what I want. Time needs to progress if I append a sequence to another. So what I really want is something like Time=1,'a' Time=2,'a' Time=3,'b' This implies that time is shifted to the next integer, but this is not always the case. I need to know about some kind of alignment. In music this translates to let a sequence start at the beginning of a bar, or half bar or quarter note or whatever. So I want to write y = s1*2 + s2(align=10) which should iterate as Time=1,'a' Time=2,'a' Time=10,'b' I have no difficulty passing align to the object (using __call__) and use it while I furnish my own __iter__() method. However I don't quite see how I can do this with bare itertools, though I may be wrong here. Bare in mind that it is not only about somehow getting the job done. The beauty of the resulting syntax is also important. In that case why not just assume that the timing of a sequence is relative to the current time unless the align argument is given? You might also need an event of zero duration to set the start time for a sequence. regards Steve -- Steve Holden +1 571 484 6266 +1 800 494 3119 PyCon is coming! Atlanta, Feb 2010 http://us.pycon.org/ Holden Web LLC http://www.holdenweb.com/ UPCOMING EVENTS:http://holdenweb.eventbrite.com/ -- http://mail.python.org/mailman/listinfo/python-list
Re: new.instancemethod __iter__
Steve Holden wrote: y = s1*2 + s2(align=10) which should iterate as Time=1,'a' Time=2,'a' Time=10,'b' I have no difficulty passing align to the object (using __call__) and use it while I furnish my own __iter__() method. However I don't quite see how I can do this with bare itertools, though I may be wrong here. Bare in mind that it is not only about somehow getting the job done. The beauty of the resulting syntax is also important. In that case why not just assume that the timing of a sequence is relative to the current time unless the align argument is given? Well that's pretty much what I'm doing. I just fail to see how I can do this with bare itertools. Currently I am doing it in the following way: When I call a Sequence as in s2(align=2) I create a new Sequence where the align value is simply stored in an instance variable. When creating the sum of two sequences, I create a Sequence with a new iter() method which first iterates over self and then over the second Sequence. But each time it has to look up the align value of the respective sequence and adjust time accordingly. Appending the two Sequences is the easy part, but adjusting time is the difficult part. My impression was, that itertools can only help to solve the first part. I may be missing something obvious. If that's the case, please let me know. -- http://mail.python.org/mailman/listinfo/python-list
Re: new.instancemethod __iter__
Martin Drautzburg wrote: Steve Holden wrote: y = s1*2 + s2(align=10) which should iterate as Time=1,'a' Time=2,'a' Time=10,'b' I have no difficulty passing align to the object (using __call__) and use it while I furnish my own __iter__() method. However I don't quite see how I can do this with bare itertools, though I may be wrong here. Bare in mind that it is not only about somehow getting the job done. The beauty of the resulting syntax is also important. In that case why not just assume that the timing of a sequence is relative to the current time unless the align argument is given? Well that's pretty much what I'm doing. I just fail to see how I can do this with bare itertools. Currently I am doing it in the following way: When I call a Sequence as in s2(align=2) I create a new Sequence where the align value is simply stored in an instance variable. When creating the sum of two sequences, I create a Sequence with a new iter() method which first iterates over self and then over the second Sequence. But each time it has to look up the align value of the respective sequence and adjust time accordingly. Appending the two Sequences is the easy part, but adjusting time is the difficult part. My impression was, that itertools can only help to solve the first part. I may be missing something obvious. If that's the case, please let me know. Perhaps I am assuming too much of your simulation environment/player. I presumed that there would be a global current time value that would be passed into or available to the play method of the sequences. However I can see that you might need something more complex if (e.g.) you want to be able to start playing at an arbitrary point in time. regards Steve -- Steve Holden +1 571 484 6266 +1 800 494 3119 PyCon is coming! Atlanta, Feb 2010 http://us.pycon.org/ Holden Web LLC http://www.holdenweb.com/ UPCOMING EVENTS:http://holdenweb.eventbrite.com/ -- http://mail.python.org/mailman/listinfo/python-list
new.instancemethod __iter__
Hello all When I create an Object and set its __iter__ method from outside s = Sequence #one of my own classes s.__iter__ = new.instancemethod(f,s,Sequence) I get different results, depending on whether I call for x in y.__iter__(): print x or for x in y: print x The first case does what I expected, i.e. it iterates over whatever f() yields. In the second case nothing is printed. I have the impression that it still calls the original __iter__() method (the one defined at the class level). Why is that so? How can I replace the __iter__() method so it does what I want. The reason I want to do such things is I need to implement operations similar to what itertools do. However I want my own classes and the operations are only similar to itertools, but differ in significant details. -- http://mail.python.org/mailman/listinfo/python-list
Re: new.instancemethod __iter__
On Sat, 06 Feb 2010 23:53:53 +0100, Martin Drautzburg wrote: Hello all When I create an Object and set its __iter__ method from outside s = Sequence #one of my own classes s.__iter__ = new.instancemethod(f,s,Sequence) I'm confused as to why you are aliasing your class before changing it. The above just makes s an alternative name for Sequence. Did you mean this? s = Sequence() # make an instance of the class I get different results, depending on whether I call for x in y.__iter__(): print x What's y? Where does it come from? Is y supposed to be an instance of Sequence? or for x in y: print x The first case does what I expected, i.e. it iterates over whatever f() yields. In the second case nothing is printed. I have the impression that it still calls the original __iter__() method (the one defined at the class level). Yes, that's almost certainly what is happening. As an optimization, Python bypasses the instance for special methods __NAME__. Why is that so? How can I replace the __iter__() method so it does what I want. The best solution is, find another way to do what you want. The clunky solution is to use delegation to wrap your class, and have the outer class re-direct calls to special methods to the instance first. The reason I want to do such things is I need to implement operations similar to what itertools do. However I want my own classes and the operations are only similar to itertools, but differ in significant details. I don't understand this. If you want iterator operations similar to itertools, why does this mean you need to replace anything? Just create your own iterators. Or use pre-processing and post-processing to get what you want. Can you show an example of what you would like to happen? -- Steven -- http://mail.python.org/mailman/listinfo/python-list
Re: new.instancemethod __iter__
Martin Drautzburg wrote: The first case does what I expected, i.e. it iterates over whatever f() yields. In the second case nothing is printed. I have the impression that it still calls the original __iter__() method (the one defined at the class level). Why is that so? How can I replace the __iter__() method so it does what I want. Virtually all __magic__ methods are looked up on the type, not the instance. So obj.__iter__() translates into type(obj).__iter__(obj). If you *really* need to overwrite __iter__ on your instance rather than defining it on your class, you need to proxy the method call: class MyObject(object): def __iter__(self): return self.myiter() obj = MyObject() obj.myiter = myiter That should do the trick. Christian -- http://mail.python.org/mailman/listinfo/python-list