Re: Finding the instance reference of an object
On Oct 17, 5:39 pm, Joe Strout <[EMAIL PROTECTED]> wrote: > On Oct 17, 2008, at 3:19 PM, Grant Edwards wrote: > > >> And my real point is that this is exactly the same as in every > >> other modern language. > > > No, it isn't. In many other languages (C, Pascal, etc.), a > > "variable" is commonly thought of as a fixed location in memory > > into which one can put values. Those values may be references > > to objects. > > Right, though not in languages like C and Pascal that don't HAVE the > notion of objects. We really ought to stop bringing up those > dinosaurs and instead compare Python to any modern OOP language. > > > In Python, that's not how it works. There is no > > "location in memory" that corresponds to a variable with a > > particular name the way there is in C or Pascal or Fortran or > > many other languages. > > No? Is there any way to prove that, without delving into the Python > source itself? > > If not, then I think you're talking about an internal implementation > detail. I think this "uncontrived" example addresses the (C/C++)/Python difference fairly directly. -- C: struct {int a;} s1, s2; int main() { s1.a = 1; s2 = s1; printf("s1.a %d s2.a %d\n", s1.a, s2.a); s1.a = 99; printf("s1.a %d s2.a %d\n", s1.a, s2.a); } -- Python: class mystruct: pass s1 = mystruct() s1.a = 1 s2 = s1 print "s1.a %2d s2.a %2d" % (s1.a,s2.a) s1.a = 99 print "s1.a %2d s2.a %2d" % (s1.a,s2.a) --- C OUTPUT: s1.a 1 s2.a 1 s1.a 99 s2.a 1 Python OUTPUT: s1.a 1 s2.a 1 s1.a 99 s2.a 99 Note that in C (or C++) the value of s2.a remains unchanged, because the VALUE of s1 (the contents of the memory where s1 resides) was COPIED to the memory location of s2, and subsequently, only the VALUE of s2.a was changed. In Python, s2.a is "changed" (but not really) because it turns out that s2 is just another name for the object that s1 pointed to. So there is no programatically accessible "location in memory" that corresponds to s1 or s2 in Python. There is only a location in memory that corresponds to the object that s1 is currently pointing to. In C, by contrast, there are definite locations in memory that correspond to both variables s1 and s2, and those locations remain always separate, distinct and unchanged throughout the execution of the program. This is not an "implementation detail", it is a fundamental part of each language. As C was an "improvement" on assembler, the variable names have always just been aliases for memory locations (or registers). You can see this in the output of any C/C++ compiler. In Python, variables are just names/aliases for *references* to objects, not names for the objects/values themselves. The variable names themselves do not correspond directly to the objects' memory locations. While yes, technically, it is true that those reference values must be stored somewhere in memory, *that* is the implementation detail. But is is not the *locations* of these references (i.e., the locations of the Python *variables*) that are copied around, it is the references themselves (the locations of the Python *objects*) that are copied. > > All that exists in Python is a name->object mapping. > > And what does that name->object mapping consist of? At some level, > there has to be a memory location that stores the reference to the > object, right? I think this is answered above, but just to drive it home, in Python the memory locations of the variables themselves (an implementation detail), which hold the references to the objects, are inaccessible . In C/C++, by contrast, variable names correspond directly to memory locations and objects, and you can easily find the addresses of variables, and the addresses do not change, although the values can. In C/C++, if you choose, you may have a variable that is itself a reference/pointer to some other memory/object/array. In C, we would say that the VALUE of that variable is the memory address of another object. But you can, if you need to, get the address of the pointer variable, which points to the *address* of the other object. In Python, a variable is ONLY EVER a reference to an object. You cannot get the address of a Python variable, only of a Python object. Hope this clears things up. dale -- http://mail.python.org/mailman/listinfo/python-list
Re: Finding the instance reference of an object
[I am actually enjoying this discussion, even though it does not address the OP's question. It is helping to solidify *my* understanding.] Joe Strout wrote: On Oct 27, 2008, at 12:19 PM, [EMAIL PROTECTED] wrote: I think this "uncontrived" example addresses the C/Python difference fairly directly (both were tested): That's correct, but of course, C is a decades-old language barely a step above assembler. For a fair comparison, pick any modern OOP language, including the C derivatives (C++, Objective-C, Java), and compare a Python object to an object in that language, rather than to a struct. Okay, sorry, should have had C++ from the start. See my spiffed-up example here, where I magically convert to C++ by replacing "struct" with "class" and adding the word "public:". Still behaves the same, though. I added the functions ByVal() and ByRef() to show that when you pass by value, the contents of the object cannot be changed. This is not possible in Python unless a copy of the object is made (which is what C++ does automatically for you in pass-by-value). In Python, the contents of the object are changed, which is most similar to the pass by reference (or by pointer) construct in C++. But, yes, as you say, technically: passing the object by reference == passing the address of the object by value. But I think that is, to most programmers, a surprising use of the term "pass by value". And note in my example, nowhere do I explicitly take the address of s1. The compiler does this for me in the ByRef() case. And nowhere to I make a copy of s1. Again, the compiler does this for me in the ByVal() case. The calls to ByVal() and ByRef() are identical. You cannot tell from the calls which thing is going to happen. --- class MyClass {public: int a;} s1, s2; void ByVal(MyClass obj) {obj.a=42;} void ByRef(MyClass &obj) {obj.a=43;} int main() { s1.a = 1; s2 = s1; printf("s1.a %2d s2.a %2d\n", s1.a, s2.a); s1.a = 99; printf("s1.a %2d s2.a %2d\n", s1.a, s2.a); ByVal(s1); printf("s1.a %2d\n", s1.a); ByRef(s1); printf("s1.a %2d\n", s1.a); } -- class mystruct: pass def ByObject(obj): obj.a=42 s1 = mystruct() s1.a = 1 s2 = s1 print "s1.a %2d s2.a %2d" % (s1.a,s2.a) s1.a = 99 print "s1.a %2d s2.a %2d" % (s1.a,s2.a) ByObject(s1) print "s1.a %2d" % (s1.a) -- C++ OUTPUT s1.a 1 s2.a 1 s1.a 99 s2.a 1 # note s2.a does not change when s1.a is modified s1.a 99# contents of s1.a does not change when passed by val s1.a 43# it does change when passed by ref Python OUTPUT s1.a 1 s2.a 1 s1.a 99 s2.a 99 # s2.a "changes" because it's the same object as s1 s1.a 42# Contents of object does change with function call. ...and in Python, of course, as you say, what you call the "value" of s1, the address of the object, id(val), does not change. >> >> [skipping lots of stuff we agree on!] >> In C/C++, by contrast, variable names correspond directly to memory locations and objects, and you can easily find the addresses of variables. Hmm, no, the C++ equivalent of an object reference would be: SomeClass* foo; Whoah, nonsequitor there. Let's back up. I did not use the word "reference", and that is the point. And I am correct that C variable names correspond to memory locations (or sometimes CPU registers - optimizers can really mangle things). And you can get the addresses of the variables themselves using the & operator. Have a look at my example code again. s1 and s2 ARE OBJECTS THEMSELVES, they are not references to objects. You can do this in C++ (not in Python). You can pass whole objects, by value (they are copied by the compiler), on the stack. And we both understand that you can't do that in Python. That is why we differentiate between "pass by reference" and "pass by value" in C++, and people generally understand what that means. > ... void NiftyMethod2(SomeClassPtr &arg) {...} ... NiftyMethod2(foo); Now, arg here is passed by reference (just like a ByRef parameter in RB or .NET). That means that NiftyMethod2 could very well change the value that is passed in. It could actually make foo point to something else. No Python method can do that, Yes, absolutely agreed. A Python method can never change *which* object the caller points to, it can only change the *contents* of that object. But the same is true in C++ as well. In your example, the address of the foo variable itself can never be changed. You can change the *value* of foo (so it points to a different object), or you can change the contents of the object foo points to. foo is a variable with an address which you can usually see with a printf("%x", &foo), and that is different from the address of the object which you get when you say printf("%x", foo). The value &foo cannot be changed. because Python arguments are ALWAYS passed by value. There is no call
Re: Finding the instance reference of an object
On Oct 28, 2:33 am, "Gabriel Genellina" <[EMAIL PROTECTED]> wrote: > En Tue, 28 Oct 2008 01:16:04 -0200, Dale Roberts <[EMAIL PROTECTED]> > escribió: > > > > > So, then, what to tell a C++ programmer about how Python passes > > arguments? You say: tell them Python only passes by value. I disagree, > > because I think that would confuse them. Rather than try to map C++ > > conventions onto Python, I think it is more useful to just tell them how > > it really works. Maybe a few statements like this: > > > All values in Python are objects, from simple integers up to complex > > user-defined classes. > > > An assignment in Python binds a variable name to an object. The > > internal "value" of the variable is the memory address of an object, > > and can be seen with id(var), but is rarely needed in practice. > > > The "value" that gets passed in a Python function call is the address > > of an object (the id()). > > > When making a function call, myfunc(var), the value of id(var) can > > never be changed by the function. > > > Not sure if these are the best. To get into much more detail, you have > > to start explaining mutable and immutable objects and such. > > I don't think the above explanation is desirable, nor needed. Objects in > Python don't have an "address" - it's just a CPython implementation > detail. The fact that id() returns that address is just an implementation > detail too. The calling mechanism should be explained without refering to > those irrelevant details. > > -- > Gabriel Genellina I agree that it was a feeble and ill-advised attempt, and would like to strike those lines from the record... But the rest of the post is strong and accurate, I think, and coming from a mainly C/C++ background, visualizing these object references being passed around does help improve my understanding of Python's *behavior* (and it apparently helps Joe too). [May I refer to you as "Joe The Programmer" in my rhetoric? Are you a "licensed" programmer making over $250K/year? ;-)] If asked by a C++ programmer about Python's argument passing, I will go with the Pass By Object explanation (which is why I called my Python routine above ByObject()). Although there will be more 'splaining to do, at least it will give the C++ programmer pause, and help them realize that there is something a little different that they need to stop and try to understand. If I just say "Python is Pass By Value, Period" without further explanation, they will expect things to work as in my ByValue() example above (where the caller's object contents cannot be changed), and that is incorrect. And they may go and tell someone else, without the detailed explanation, that "Dale says it's Pass By Value", and I'll get blamed when their function surprisingly changes the contents of the caller's object. If I just say "Python is Pass By Reference", that is wrong too. As Joe The Programmer points out, they will expect that the calling *variable* itself can be changed, and that is wrong too. They need to understand that Python does not map neatly, directly, and completely to their C++ experience of Pass By Value (which involves copying a variable), or Pass By Reference (which involves taking the address of a variable). The Key Concept in for a C++ programmer looking at Python is that, unlike in C++, **Variables Cannot "Contain" Values**. All values in Python are objects, and all variables in Python simply point to, or are bound to, or refer to, these objects. The variables themselves do not contain the objects - if you must (like Joe the Programmer), you can say that all Python variables *contain* an object reference, and it is these references that are passed around. Unlike C++, an object reference is the ONLY thing that a Python variable can contain. A function parameter is always passed as a reference to an object, not a reference to a variable, or a copy of a variable or object. And that is where the confusion arises. When people say ByRef or ByVal, they usually mean by Reference to (address) or Value of (copy) the *contents* of the passed variable. But, PYTHON VARIABLES DO NOT "CONTAIN" VALUES (sorry for the shouting, but it is the most important point here), so ByRef and ByVal lose their commonly accepted meanings. In C++, ByValue requires a copy (and Python does not copy). In C++, ByReference requires the address of a *variable* (an "lvalue"), and variables do not have accessible addresses in Python. ByObject, in contrast, requires neither (unless, like Joe The Programmer, you consider the "value" of a variable to be the id(), which is not what most
Re: Finding the instance reference of an object
On Oct 28, 11:59 am, Joe Strout <[EMAIL PROTECTED]> wrote: > ... > > There are only the two cases, which Greg quite succinctly and > accurately described above. One is by value, the other is by > reference. Python quite clearly uses by value. Parameters are > expressions that are evaluated, and the resulting value copied into > the formal parameter, pure and simple. The continued attempts to > obfuscate this is pointless and wrong. > > Best, > - Joe 5 + 3 What is the "value" of that expression in Python? Can you tell me? 99.99% of programmers (who do not have this thread as context) will say that the value is 8. But you say the value is the memory address of the resulting object created when the + operator is applied to the 5 object and the 3 object. That is the "value" that is copied. Okay, you can have it that way, but every time you explain to someone that Python passes "By Value", you will have to add the additional baggage that, oh, by the way, there is a completely different meaning for "value" in Python than what you are used to. Then the questions and puzzled looks will start... And when they tell their friend that Joe The Programmer said it's Pass By Value, your additional context may not be present any longer, and the friend will be very confused. In my opinion, best just to head it off and call it something different so as not to confuse. dale -- http://mail.python.org/mailman/listinfo/python-list
Re: Finding the instance reference of an object
On Oct 28, 11:59 am, Joe Strout <[EMAIL PROTECTED]> wrote: > ... > > There are only the two cases, which Greg quite succinctly and > accurately described above. One is by value, the other is by > reference. Python quite clearly uses by value. Parameters are > expressions that are evaluated, and the resulting value copied into > the formal parameter, pure and simple. The continued attempts to > obfuscate this is pointless and wrong. > > Best, > - Joe Joe, you are being too generous and expansive here. [Play along with me for a minute here...] Don't you know? There is really only *ONE* case, and, you are right, it is Pass By Value. There is no such thing as Pass By Reference at the physical CPU level at all, right? If there is, show it to me. Pass By Reference is just a silly idiom developed by high-minded CS academics to confuse the rest of us. It has no practical use and should not be given its own name, when we already have a good an proper name for it. Let me demonstrate with 3 examples of a function definition, and the appropriate calling syntax for that function in C++, all sharing the common "int i" global variable: int i = 5; myfunc(int &val){} /*CALL:*/ myfunc(i);// "ByRef" (ya, right!) myfunc(int val){}/*CALL:*/ myfunc(i);// ByVal myfunc(int *val){} /*CALL:*/ myfunc(&i); // Joe's ByVal The first is what all the fakers call "Pass By Reference" - sheesh, how naive. We all know that what *really* happens internally is that the *address* of val (A VALUE itself, or course) is copied and passed on the stack, right? There couldn't be a more straightforward example of Pass By Value (unless it's an inline function, or optimized away, or possibly when implemented in a VM, or...). It passes the *address* of i by value, then we can access the *value* of i too via indirection. Hmm, did we need to have two definitions of VALUE there? Well, never mind, no one will notice... The next is obviously pass by value. It's right out there. The value of i (which is what we are talking about, right?) is copied out, and passed right on the stack in plain daylight where we can all see it. How about the third? Pass By Value, obviously, of course. This is the version you are defending, right? The parameter's value, &i, is evaluated and copied right onto the stack, just like in the first example. In fact, if you compare the assembler output of the first and third examples, you may not even see a difference. Never mind the actual contents of that pesky "i" variable that most people are referring to when they use the term "value". We don't need to dress up example 3 and call it an "idiom" where we are really passing a so- called "reference" of the variable "i". Indeed! Don't insult our intelligence. We can all see that it's an address passed by value, plain and simple. Pass By Reference? So "postmodern". Who needs it. Show me a so-called "reference". I've looked at the assembler output and have never seen one. There is no such thing. "The continued attempts to obfuscate this is pointless and wrong." --- I hate to have to add this, but for those not paying close attention: ;-) dale (tongue back out of cheek now) -- http://mail.python.org/mailman/listinfo/python-list
Re: Finding the instance reference of an object
On Oct 29, 9:13 pm, Joe Strout <[EMAIL PROTECTED]> wrote: > On Oct 29, 2008, at 4:52 PM, Fuzzyman wrote: > > > You're pretty straightforwardly wrong. In Python the 'value' of a > > variable is not the reference itself. > > That's the misconception that is leading some folks around here into > tangled nots of twisty mislogic, ultimately causing them to make up > new terms for what every other modern language is perfectly happy > calling Call-By-Value. Doesn't this logic also apply to Call By Reference? Isn't that term redundant too? (see my 3 C++ examples above). If not, why not? Are you saying that C++ is capable of using the Call By Reference idiom, but C is not, because C does not have a reference designation for formal function parameters? "Call By Object Reference" is an idiom, just like Call By Reference. It is not a physical description of what is going on internally at the register/stack level (which is always just shuffling values around - or flipping bits, as Steven points out), it is a higher level concept that helps people understand the *intention* (not necessarily the implementation) of the mechanism. You cannot look a C++ programmer straight in the eye and say that "Python uses Call By Value, Period", without also informing them that "Python variables can ONLY EVER hold object references - that is the only "value" they can ever hold". Then the C++ programmer will go "Oh, yea, that makes sense". Instead of having to say all of that, we just give it a new name. Instead of "Call By Value, Where Every Single Value Is Only Ever A Reference To An Object Which Contains The Actual Value That Programmers Usually Refer To", we just say "Call By Object Reference". > ... > 2. Because everything in Python is an object, you're not forced to > think clearly (and more generally) about references as values I think we've shown that we are all in fact thinking clearly about it, and we all (you included, of course!) understand what is going on. It's just a matter of what words we choose to describe it. Using your definition of value, though, I believe that if you want to throw out Call By Object Reference, you also have to throw out Call By Reference. See my 3 C++ examples above. And just for fun I did look at the assembler output, and, indeed, the output for examples 1 and 3 is absolutely identical. They are the same thing, as far as the CPU is concerned. Would you give them different names? dale -- http://mail.python.org/mailman/listinfo/python-list
Re: Finding the instance reference of an object
On Oct 30, 11:03 am, Joe Strout <[EMAIL PROTECTED]> wrote: > ... >> Are you saying that C++ is capable of using the Call By Reference idiom, >> but C is not, because C does not have a reference designation for formal >> function parameters? > > It's been a LONG time since I did anything in C, but yes, I believe > that reference parameters were an addition that came with C++. Okay, I completely understand you, and I think we will just have to agree to disagree about the best term to use for Python's parameter passing mechanism, and this will likely be my concluding post on this topic (although I have enjoyed it very much and have solidified my own understanding). I even found a few web sites that very strongly support your viewpoint (as it relates to Java): http://www.ibm.com/developerworks/library/j-praxis/pr1.html http://javadude.com/articles/passbyvalue.htm http://www.yoda.arachsys.com/java/passing.html The difference is that I would say that C supports the Pass By Reference idiom using this syntax: myfunc(int *val){} /*CALL:*/ myfunc(&i); which actually passes an address expression (not a variable) by value, but "looks and feels" like a reference to the "i" variable, which contains the real value that we care about - and allows modification of that value. C++ adds a syntactic change for this very commonly used C idiom, but does not add any new capability - the results are absolutely indistinguishable. Python, likewise, in relation to the values we care about (the values contained only in objects, never in variables) behaves like Call by Object Reference. If I tell someone that Python uses only Call By Value (and that is all I tell them), they may come away with the impression that variables contain the values they care about, and/or that the contents of objects are copied, neither of which is the case, even for so-called "simple", immutable objects (indeed, at the start of this thread, you said you believed that, like Java, simple values were contained within Python variables). But Python, unlike Java or most other commonly used languages, can ONLY EVER pass an object reference, and never an actual value I care about, and I think that idiom deserves a different name which distinguishes it from the commonly accepted notion of Pass By Value. Thanks for a thoughtful discussion, dale -- http://mail.python.org/mailman/listinfo/python-list
Re: Finding the instance reference of an object
On Oct 30, 3:06 pm, Dale Roberts <[EMAIL PROTECTED]> wrote: > ... that idiom deserves a different name which > distinguishes it from the commonly accepted notion of Pass By Value. Bah, what I meant to end with was: Just as the Pass By Reference idiom deserves a unique name to distinguish it from Pass By Value (even though it is often Pass By (address) Value internally), so Pass By Object Reference deserves a unique name (even though it too is Pass By (reference) Value internally). Again, thanks for the discussion, dale -- http://mail.python.org/mailman/listinfo/python-list
Re: Finding the instance reference of an object
On Oct 31, 3:15 am, greg <[EMAIL PROTECTED]> wrote: > Dale Roberts wrote: > > Just as the Pass By Reference idiom deserves a unique name to > > distinguish it from Pass By Value (even though it is often Pass By > > (address) Value internally), so Pass By Object Reference deserves a > > unique name (even though it too is Pass By (reference) Value > > internally). > > Since Python only has one parameter passing mechanism, > there's no need to give it a name at all. If you're > having to explain it, just explain it, and don't > bother naming it! > > -- > Greg On Oct 31, 3:15 am, greg <[EMAIL PROTECTED]> wrote: > Dale Roberts wrote: > > Just as the Pass By Reference idiom deserves a unique name to > > distinguish it from Pass By Value (even though it is often Pass By > > (address) Value internally), so Pass By Object Reference deserves a > > unique name (even though it too is Pass By (reference) Value > > internally). > > Since Python only has one parameter passing mechanism, > there's no need to give it a name at all. If you're > having to explain it, just explain it, and don't > bother naming it! > > -- > Greg But then why bother having any other names at all for other languages that have only one calling mechanism, like Call By Name, Call By Macro Expansion, etc. If it is a different process, it needs a different name. OR, as you suggest, no name at all, just an explanation. But please don't give it the WRONG name! -- http://mail.python.org/mailman/listinfo/python-list
Re: Finding the instance reference of an object
On Oct 31, 2:27 am, greg <[EMAIL PROTECTED]> wrote: > Dale Roberts wrote: > > Are you > > saying that C++ is capable of using the Call By Reference idiom, but C > > is not, because C does not have a reference designation for formal > > function parameters? > > Call by reference is not an "idiom", it's a *language > feature*. > ... > You can use an idiom in C to get the same effect, but this > is not the same thing as the language having it as a feature. Okay, I'll grant that, but is there a language other than Python that uses the Call By Value feature that does not do it by assigning/ copying the result of an expression into the formal parameter? The terms "result" and "value" are generally understood to refer to the working data of the program, not the internal workings of the interpreter, VM, or compiler. So, yes, internally the C Python runtime does use Call By Value. It's written in C after all - that's all it can do. But Call By Value is not a feature of the Python language. dale [Somebody unplug my network cable! I can't stop!] -- http://mail.python.org/mailman/listinfo/python-list
Re: any(), all() and empty iterable
On Apr 14, 8:33 am, Tim Chase wrote: > ... > I still prefer "Return False if any element of the iterable is > not true" or "Return False if any element in the iterable is > false" because that describes exactly what the algorithm does. I agree that the original doc comment is not helpful as it stands (even though the behavior of any() is of course correct!), and prefer Tim's alternative. Since Python is used by programmers (hopefully!), the doc comment should be directed toward that audience. It should be unambiguous, and should not assume everyone has perfect knowledge of mathematical logic operations, or that Python necessarily follows the rules that a logician would expect (take the varying behavior of "modulo" operators in various languages as an example). Pure logic aside, if I was presented with the original comment ('Return True if all elements of the iterable are true.') as a specification, as a programmer I would immediately have to ask what to do in the case of an empty list. It might be that the user hadn't thought about it, or would want to throw an exception, or return False. The doc should speak to the intended audience: programmers, who like to make sure all bases and cases are covered. dale -- http://mail.python.org/mailman/listinfo/python-list
Re: any(), all() and empty iterable
On Apr 16, 2:27 pm, Tim Chase wrote: > Raymond Hettinger wrote: > > I will not change the sentence to "return false if any element > > of the iterable is false." The negations make the sentence > > hard to parse mentally > > Just as a ribbing, that "return X if any element of the iterable > is X" is of the same form as the original. The negation is only > of the X, not of the sentence structure. > > > I will probably leave the lead-in sentence as-is but may > > add another sentence specifically covering the case for > > an empty iterable. > > as one of the instigators in this thread, I'm +1 on this solution. Yes, I now appreciate the motivation for having the word "all" in the text, and simply adding something like "or the iterable is empty" might head off future confusion. dale -- http://mail.python.org/mailman/listinfo/python-list
send() to a generator in a "for" loop with continue(val)??
I've started using generators for some "real" work (love them!), and I need to use send() to send values back into the yield inside the generator. When I want to use the generator, though, I have to essentially duplicate the machinery of a "for" loop, because the "for" loop does not have a mechanism to send into the generator. Here is a toy example: def TestGen1(): for i in xrange(3): sendval = yield i print " got %s in TestGen()" % sendval g = TestGen1() sendval = None try: while True: val = g.send(sendval) print 'val in "while" loop %d' % val sendval = val * 10 except StopIteration: pass I have to explicitly create the generator with an assignment, send an initial None to the generator on the first go, then have to catch the StopIteration exception. In other words, replicate the "for" mechanism, but use send() instead of next(). It would be nice if I could just do this instead: for val in TestGen1(): print 'val in "for" loop %d' % val continue(val*10) ...or something similar. Is this an old idea? Has it been shot down in the past already? Or is it worth pursuing? I Googled around and saw one hit here: http://mail.python.org/pipermail/python-ideas/2009-February/003111.html, but not much follow-up. I wonder if people want to keep the idea of an "iterator" style generator (where send() is not used) separate from the idea of a "co- routine" style generator (where send() is used). Maybe combining the two idioms in this way would cause confusion? What do folks think? dale -- http://mail.python.org/mailman/listinfo/python-list
Re: send() to a generator in a "for" loop with continue(val)??
On Apr 17, 10:07 pm, Aaron Brady wrote: > You can do it with a wrapping generator. I'm not sure if it > interferes with your needs. It calls 'next' the first time, then just > calls 'send' on the parameter with the value you send it. Aaron, Thanks for the hint. I'd made a modified version of my generator that was "for loop aware" and had two yields in it, but this seemed very fragile and hackish to me, and left my generator only usable inside a "for" loop. The wrapper method seems to be a much better way to go. dale -- http://mail.python.org/mailman/listinfo/python-list
Re: send() to a generator in a "for" loop with continue(val)??
On Apr 19, 6:10 am, Peter Otten <__pete...@web.de> wrote: > ... > I only just started reading Beazley's presentation, it looks interesting. > Thanks for the hint! > > Are you currently using coroutines in Python? If so, what kind of practical > problems do they simplify for you? I thought I'd chime in with an application too. I am using this mechanism to implement a state machine. I read through Beazley's presentation too - wow, lots of ideas in there. For my simple state machine, I am using a very simple "trampoline" function (see his slides starting at about #172). My "run" routine is a bit different, but the idea is similar. I'm using this to present images to a test subject (a person looking at a computer screen), and the person's responses guide the state machine. So I need to get data in (the subject responses) and out (the next image to be presented). So I have violated The Beazley Principle of slide #195: Keeping it Straight • If you are going to use coroutines, it is critically important to not mix programming paradigms together • There are three main uses of yield • Iteration (a producer of data) • Receiving messages (a consumer) • A trap (cooperative multitasking) • Do NOT write generator functions that try to do more than one of these at once ...whoops! But I think this is a valid use of the mechanism, in that it is very localized and self contained to just the few routines that make up the state machine. It works very well, makes it easy to implement the state machine clearly, and is easy to understand and maintain. I can see where it could get very confusing to use this mechanism in a more general way. dale -- http://mail.python.org/mailman/listinfo/python-list