Re: Return value of an assignment statement?
Jeff Schwab a écrit : [EMAIL PROTECTED] wrote: What you can't do (that I really miss) is have a tree of assign-and-test expressions: import re pat = re.compile('some pattern') if m = pat.match(some_string): do_something(m) else if m = pat.match(other_string): do_other_thing(m) else: do_default_thing() What you want is: for astring, afunc in ((some_string, do_something), (other_string, do_other_thing)): m = pat.match(astring) if m: afunc(m) break else: do_default_thing() That looks like the first realistic alternative I've seen. I find the flow a little hard to follow, but I think that's mostly just because I'm not accustomed to the syntax. Possibly. It may also have to do with the fact that - as Carl mentions - it's a bit overkill for quite a few cases. Your approach fits in my head a little more comfortably if none of the lines are longer than eighty columns, if the for-loop isn't given an else-clause (which still looks to my untrained eye like it should match the preceding if), It tooks me some times to get used to the for/else construct, but I now find it quite elegant. And helpful, in that it warns me that 'falling thru' the iteration is expected to be a special case. and if the break-statement is replaced with a return-statement: actions = ( ('some_string', do_something), ('other_string', do_other_thing)) def find_action(pattern): for string, action in actions: m = pattern.match(string) if m: return action return do_default_thing find_action(re.compile('some pattern'))() As far as I'm concerned, I wouldn't use a function only because I don't yet feel confortable with for/else. And using a more generic version of this function may not necessarily help, unless it's really a pattern in your code (in which case the reader will quickly become familiar with it). BTW, if you want a more generic version, here's one: def find_action(test, choices, default): for arg, action in choices: result = test(arg) if result: return result, action else: return None, default actions = ( ('some_string', do_something), ('other_string', do_other_thing)) ) pat = re.compile(some_pattern) test = lambda s: pat.match(s) match, action = find_action(test, actions, do_default_thing) action(match) -- http://mail.python.org/mailman/listinfo/python-list
Re: Return value of an assignment statement?
Jeff Schwab a écrit : (snip) This is apparently section 1.9 of the Python Cookbook: http://www.oreilly.com/catalog/pythoncook2/toc.html Martelli suggests something similar to the thigamabob technique I use (he calls it DataHolder). It's really more like the xmatch posted by Paul Rubin. Martelli also says, though, that if you need this, you're not thinking Pythonically. I'd personnaly read this as: for most concrete cases, there's a Python idiom such that you don't need to set-and-test-at-once - an example being given for the concrete case of 'iterating over lines in a file'. I don't know what the Pythonic alternative is. The iterating-over-pairs approach suggested by Bruno is the only alternative I've seen. I guess it's considered the pythonic alternative for the concrete use case where there's no better idiom !-) Note that as far as I'm concerned, I don't have much problem with get-and-set (which I commonly use in most other languages allowing it). In fact I'd probably prefer an expression-based version of Python (now would it still be Python is another question...) - but that's not been so far a string enough reason to switch language... -- http://mail.python.org/mailman/listinfo/python-list
Re: Return value of an assignment statement?
Paddy a écrit : On 21 Feb, 23:33, [EMAIL PROTECTED] [EMAIL PROTECTED] wrote: What you can't do (that I really miss) is have a tree of assign-and-test expressions: import re pat = re.compile('some pattern') if m = pat.match(some_string): do_something(m) else if m = pat.match(other_string): do_other_thing(m) else: do_default_thing() What you want is: for astring, afunc in ((some_string, do_something), (other_string, do_other_thing)): m = pat.match(astring) if m: afunc(m) break else: do_default_thing() The Bruno transform? :-) I do not claim any paternity on this idiom. FWIW, must be (in one or another variant) in quite a lot of texts / posts / sites / any other resource about Python. -- http://mail.python.org/mailman/listinfo/python-list
Re: Return value of an assignment statement?
In article [EMAIL PROTECTED], Marc 'BlackJack' Rintsch [EMAIL PROTECTED] wrote: On Fri, 22 Feb 2008 11:00:17 -0800, Aahz wrote: It's just too convenient to be able to write L += ['foo'] without rebinding L. nitpickBut ``+=`` does rebind./nitpick Doesn't matter in this case but we've had confused programmers asking questions here when `L` is a class attribute and it's rebound to the instance, or if they tried it on a list in a tuple. Extending a list that's a read only property doesn't work either. Fair point. And in fact the original primary use case for allowing the target of augmented assignment to return self was NumPy. Being able to use the simple syntax of augmented assignment instead of method calls in order to avoid copying huge arrays was a big win. (Which you probably know, but there are other people reading this thread who don't.) -- Aahz ([EMAIL PROTECTED]) * http://www.pythoncraft.com/ All problems in computer science can be solved by another level of indirection. --Butler Lampson -- http://mail.python.org/mailman/listinfo/python-list
Re: Return value of an assignment statement?
On Sat, 23 Feb 2008 22:44:30 +, Tim Roberts wrote: Marc 'BlackJack' Rintsch [EMAIL PROTECTED] wrote: On Fri, 22 Feb 2008 11:00:17 -0800, Aahz wrote: It's just too convenient to be able to write L += ['foo'] without rebinding L. nitpickBut ``+=`` does rebind./nitpick Usually, but there's an exception for lists, which a specific implementation for += that calls append. Or do I misunderstand you? Terry Reedy showed the tuple proof, here's the read only property case:: class A(object): def __init__(self): self._data = list() @property def data(self): return self._data a = A() a.data += [42] Output:: Traceback (most recent call last): File test.py, line 25, in module a.data += [42] AttributeError: can't set attribute Ciao, Marc 'BlackJack' Rintsch -- http://mail.python.org/mailman/listinfo/python-list
Re: Return value of an assignment statement?
On Fri, 22 Feb 2008 11:00:17 -0800, Aahz wrote: It's just too convenient to be able to write L += ['foo'] without rebinding L. nitpickBut ``+=`` does rebind./nitpick Doesn't matter in this case but we've had confused programmers asking questions here when `L` is a class attribute and it's rebound to the instance, or if they tried it on a list in a tuple. Extending a list that's a read only property doesn't work either. Ciao, Marc 'BlackJack' Rintsch -- http://mail.python.org/mailman/listinfo/python-list
Re: Return value of an assignment statement?
in 335100 20080222 123210 Steven D'Aprano [EMAIL PROTECTED] wrote: On Fri, 22 Feb 2008 08:12:56 +, Marc 'BlackJack' Rintsch wrote: A variable in programming languages is composed of a name, a memory location, possibly a type and a value. In C-like languages, where you put values in named and typed boxes, the memory location and type are attached to the name. In Python both belong to the value. But Python objects don't have names, so by your own definition, they aren't variables. Names are associated with namespaces, not objects. A name must have one and only one object bound to it at any one time; objects on the other hand can be bound to one name, or no name, or a thousand names. The object itself has no way of knowing what names it is bound to, if any. Or, to put it another way... Python doesn't have variables. In that case neither does any other OO language. -- http://mail.python.org/mailman/listinfo/python-list
Re: Return value of an assignment statement?
Dennis Lee Bieber wrote: On Fri, 22 Feb 2008 11:23:27 -0800, Jeff Schwab [EMAIL PROTECTED] declaimed the following in comp.lang.python: I'm about through with this discussion, but FWIW, this is a real gotcha for me and many others. This is a case where Python does not do what many programmers expect, and it at least takes some getting used-to. As opposed to the twice monthly shocked newbie discovering that a mutable as a function default doesn't reset on the next invocation? In that aspect, it all comes down to the difference between mutables and immutables in Python. You know what's illuminating the discussion? Everybody thinks they understand this issue, but the explanations are contradictory. It seems like half the folks think this is an issue of mutability vs. immutability, and the other half believe that has nothing to do with it. -- http://mail.python.org/mailman/listinfo/python-list
Re: Return value of an assignment statement?
Paul Rubin wrote: Steven D'Aprano [EMAIL PROTECTED] writes: Personally, I think the confusion of augmented assignments is not worth the benefit of saving typing a couple of characters. I think Guido's first decision, to leave += etc out of the language, was the right decision. It quite helpful to be able to say foo['bar'+lookup(baz)][blob(a)+frob(b)] += 1 without having to split it into separate statements to avoid repeating the function calls and their possible side effects. And that was the reason for eventually including them. I remember being very surprised when I learned that rebinding was possible at the option of the implementing object, but of course rebinding is inevitable when you have immutable objects that implement augmented assignments. regards Steve -- Steve Holden+1 571 484 6266 +1 800 494 3119 Holden Web LLC http://www.holdenweb.com/ -- http://mail.python.org/mailman/listinfo/python-list
Re: Return value of an assignment statement?
[EMAIL PROTECTED] wrote: What you can't do (that I really miss) is have a tree of assign-and-test expressions: import re pat = re.compile('some pattern') if m = pat.match(some_string): do_something(m) else if m = pat.match(other_string): do_other_thing(m) else: do_default_thing() What you want is: for astring, afunc in ((some_string, do_something), (other_string, do_other_thing)): m = pat.match(astring) if m: afunc(m) break else: do_default_thing() That looks like the first realistic alternative I've seen. I find the flow a little hard to follow, but I think that's mostly just because I'm not accustomed to the syntax. Your approach fits in my head a little more comfortably if none of the lines are longer than eighty columns, if the for-loop isn't given an else-clause (which still looks to my untrained eye like it should match the preceding if), and if the break-statement is replaced with a return-statement: actions = ( ('some_string', do_something), ('other_string', do_other_thing)) def find_action(pattern): for string, action in actions: m = pattern.match(string) if m: return action return do_default_thing find_action(re.compile('some pattern'))() -- http://mail.python.org/mailman/listinfo/python-list
Re: Return value of an assignment statement?
Jeff Schwab wrote: mrstephengross wrote: Hi all. In C, an assignment statement returns the value assigned. For instance: int x int y = (x = 3) In the above example, (x=3) returns 3, which is assigned to y. In python, as far as I can tell, assignment statements don't return anything: y = (x = 3) The above example generates a SyntaxError. Is this correct? I just want to make sure I've understood the semantics. Yes, but there is valid syntax for the common case you mentioned: y = x = 3 What you can't do (that I really miss) is have a tree of assign-and-test expressions: import re pat = re.compile('some pattern') if m = pat.match(some_string): do_something(m) else if m = pat.match(other_string): do_other_thing(m) else: do_default_thing() This is apparently section 1.9 of the Python Cookbook: http://www.oreilly.com/catalog/pythoncook2/toc.html Martelli suggests something similar to the thigamabob technique I use (he calls it DataHolder). It's really more like the xmatch posted by Paul Rubin. Martelli also says, though, that if you need this, you're not thinking Pythonically. I don't know what the Pythonic alternative is. The iterating-over-pairs approach suggested by Bruno is the only alternative I've seen. -- http://mail.python.org/mailman/listinfo/python-list
Re: Return value of an assignment statement?
On 21 Feb, 23:33, [EMAIL PROTECTED] [EMAIL PROTECTED] wrote: What you can't do (that I really miss) is have a tree of assign-and-test expressions: import re pat = re.compile('some pattern') if m = pat.match(some_string): do_something(m) else if m = pat.match(other_string): do_other_thing(m) else: do_default_thing() What you want is: for astring, afunc in ((some_string, do_something), (other_string, do_other_thing)): m = pat.match(astring) if m: afunc(m) break else: do_default_thing() The Bruno transform? :-) -- http://mail.python.org/mailman/listinfo/python-list
Re: Return value of an assignment statement?
On Feb 23, 3:44 pm, Jeff Schwab [EMAIL PROTECTED] wrote: actions = ( ('some_string', do_something), ('other_string', do_other_thing)) def find_action(pattern): for string, action in actions: m = pattern.match(string) if m: return action return do_default_thing find_action(re.compile('some pattern'))() You don't need to pass the pattern, just pass the match function: def find_action(match, actions=actions, default_action=None): for string, action in actions: if match(string): return action return default_action find_action(re.compile('some pattern').match)() -- Arnaud -- http://mail.python.org/mailman/listinfo/python-list
Re: Return value of an assignment statement?
Arnaud Delobelle wrote: On Feb 23, 3:44 pm, Jeff Schwab [EMAIL PROTECTED] wrote: actions = ( ('some_string', do_something), ('other_string', do_other_thing)) def find_action(pattern): for string, action in actions: m = pattern.match(string) if m: return action return do_default_thing find_action(re.compile('some pattern'))() You don't need to pass the pattern, just pass the match function: def find_action(match, actions=actions, default_action=None): for string, action in actions: if match(string): return action return default_action find_action(re.compile('some pattern').match)() That's cool. :) -- http://mail.python.org/mailman/listinfo/python-list
Re: Return value of an assignment statement?
On Feb 23, 2:59 am, Jeff Schwab [EMAIL PROTECTED] wrote: Dennis Lee Bieber wrote: On Fri, 22 Feb 2008 11:23:27 -0800, Jeff Schwab [EMAIL PROTECTED] declaimed the following in comp.lang.python: I'm about through with this discussion, but FWIW, this is a real gotcha for me and many others. This is a case where Python does not do what many programmers expect, and it at least takes some getting used-to. As opposed to the twice monthly shocked newbie discovering that a mutable as a function default doesn't reset on the next invocation? In that aspect, it all comes down to the difference between mutables and immutables in Python. You know what's illuminating the discussion? Everybody thinks they understand this issue, but the explanations are contradictory. It seems like half the folks think this is an issue of mutability vs. immutability, and the other half believe that has nothing to do with it. You mean like this: :=) def invoke_some_fct(parent): y = parent.x try: y += [ 'world' ] except: y += ( 'world', ) print y, parent.x class abc: def __init__(self): self.x=[ 'hello' ] invoke_some_fct(self) print self.x self.x=( 'hello', ) invoke_some_fct(self) print self.x hw = abc() -- http://mail.python.org/mailman/listinfo/python-list
Re: Return value of an assignment statement?
Marc 'BlackJack' Rintsch [EMAIL PROTECTED] wrote: On Fri, 22 Feb 2008 11:00:17 -0800, Aahz wrote: It's just too convenient to be able to write L += ['foo'] without rebinding L. nitpickBut ``+=`` does rebind./nitpick Usually, but there's an exception for lists, which a specific implementation for += that calls append. Or do I misunderstand you? C:\tmppython Python 2.4.4 (#71, Oct 18 2006, 08:34:43) [MSC v.1310 32 bit (Intel)] on win32 Type help, copyright, credits or license for more information. L = [1,2,3] id(L) 10351000 L += [4] id(L) 10351000 -- Tim Roberts, [EMAIL PROTECTED] Providenza Boekelheide, Inc. -- http://mail.python.org/mailman/listinfo/python-list
Re: Return value of an assignment statement?
Tim Roberts [EMAIL PROTECTED] wrote in message news:[EMAIL PROTECTED] | Marc 'BlackJack' Rintsch [EMAIL PROTECTED] wrote: | | On Fri, 22 Feb 2008 11:00:17 -0800, Aahz wrote: | | It's just too convenient to be able to write | | L += ['foo'] | | without rebinding L. | | nitpickBut ``+=`` does rebind./nitpick | | Usually, but there's an exception for lists, which a specific | implementation for += that calls append. Or do I misunderstand you? There is no exception at the compiler level, and indeed, cannot be, because in general, the compiler *does not know* the types of either target or augment. target += augment is compiled, in effect, as compute target and load target_object compute and load augment_object call target_object.__iadd__(augment_object) store return_object at target In the list case, the rebinding is to the *same* object! -- because list.__iadd(l1,l2)__ returns l1 extended with l2 rather than a new list l1+l2, as the specification allows. Augmented (inplace) assignment is still assignment (binding). | C:\tmppython | Python 2.4.4 (#71, Oct 18 2006, 08:34:43) [MSC v.1310 32 bit (Intel)] on | win32 | Type help, copyright, credits or license for more information. | L = [1,2,3] | id(L) | 10351000 | L += [4] | id(L) | 10351000 L has been rebound to the same object, hence same id. Unfortunately, such rebinding is only visible (that I can think of) when it fails: t=([],) t[0]+=[1] Traceback (most recent call last): File pyshell#8, line 1, in -toplevel- t[0]+=[1] TypeError: object does not support item assignment t ([1],) The list comprising t[0] is extended by its __iadd__ method. The exception arises due to the subsequent attempted rebinding to t[0] (see dis output below), which is, of course, not permissible. t[0].extend([2]) t ([1, 2],) Extension without attempted illegal rebinding raises no error. CPython specifics: from dis import dis def fi(i): i+=1; return i dis(fi) 1 0 LOAD_FAST0 (i) 3 LOAD_CONST 1 (1) 6 INPLACE_ADD 7 STORE_FAST 0 (i) 10 LOAD_FAST0 (i) 13 RETURN_VALUE def fl(l): l += [1]; return l dis(fl) 1 0 LOAD_FAST0 (l) 3 LOAD_CONST 1 (1) 6 BUILD_LIST 1 9 INPLACE_ADD 10 STORE_FAST 0 (l) 13 LOAD_FAST0 (l) 16 RETURN_VALUE Treating the VM stack as a Python list, INPLACE_ADD executes something like stack[-2] = stack[-2].__iadd__(stack[-1]) stack.pop() # leaving returned object on top of stack Terry Jan Reedy -- http://mail.python.org/mailman/listinfo/python-list
Re: Return value of an assignment statement?
On Thu, 21 Feb 2008 21:28:25 -0800, Jeff Schwab wrote: So what is the variable? Or is Python the first HLL I've ever heard of that didn't have variables? Relax, Python has variables. It's just sometimes a good advice for people coming from languages like C to forget about that term for a while because they have the wrong impression of what variable means. A variable in programming languages is composed of a name, a memory location, possibly a type and a value. In C-like languages, where you put values in named and typed boxes, the memory location and type are attached to the name. In Python both belong to the value. Ciao, Marc 'BlackJack' Rintsch -- http://mail.python.org/mailman/listinfo/python-list
Re: Return value of an assignment statement?
On Feb 21, 6:52 pm, Steve Holden [EMAIL PROTECTED] wrote: mrstephengross wrote: What you can't do (that I really miss) is have a tree of assign-and-test expressions: import re pat = re.compile('some pattern') if m = pat.match(some_string): do_something(m) Yep, this is exactly what I am (was) trying to do. Oh well Any clever ideas on this front? The syntax is the way it is precisely to discourage that kind of clever idea. Don't be ridiculous. Assignment operators are maybe one of the worst things in existence, but this particular use case (running a sequence of tests like the above) is perfectly useful and good. Some Pythonistas will swear to their grave and back that should be done by factoring out the tests into a list and iterating over it, and NO OTHER WAY WHATSOEVER, but I don't buy it. That's a lot of boilerplate--the very thing Python is normally so good at minimizing-- when it might not be needed. It would be the right thing for a complex, pluggable, customizable input filter; but is rarely a better solution for a simple text processing script. Quick, at a glance, which code snippet will you understand faster (pretend you know Perl): if (/name=(.*)/) { $name = chop(\1); } elsif (/id=(.*)/) { $id = chop(\1); } elsif (/phone=(.*)/) { $phone = chop(\1); } vs. def set_phone_number(m): phone = m.group(1).strip() def set_id(m): id = m.group(1).strip() def set_name(m): name = m.group(1).strip() _line_tests = [ (rphone=(.*), set_phone_number), (rname=(.*), set_name), (rid=(.*), set_id), ] for pattern,func in _line_tests: m = re.match(pattern,line) if m: func(m) At this small scale, and probably at much larger scales too, the Perl example blows the Python example out of the water in terms of readability. And that's counting Perl's inherent unreadableness. If it were a priority, Python could support this set-and-test idiom, and without an assignment operator. (Notice Perl doesn't use assignment operator here.) For example, a syntax like this (where the scope of m is local to the if-condition and the body of the if- statement: if m where m = re.match(rname=(.*),line): name = m.group(1).strip() elif m where m = re.match(rid=(.*),line): id = m.group(1).strip() elif m where m = re.match(rphone=(.*),line): phone = m.group(1).strip() This won't happen because the set-and-test idiom is relatively minor and not deemed worthy of syntax support. But if it were there, there'd really be nothing clever about it. Carl Banks -- http://mail.python.org/mailman/listinfo/python-list
Re: Return value of an assignment statement?
On Feb 21, 4:57 pm, mrstephengross [EMAIL PROTECTED] wrote: What you can't do (that I really miss) is have a tree of assign-and-test expressions: import re pat = re.compile('some pattern') if m = pat.match(some_string): do_something(m) Yep, this is exactly what I am (was) trying to do. Oh well Any clever ideas on this front? Yeah, I got something clever. I don't recommend using it, biut def call_if_true(cond): if cond: return lambda func: func(cond) return lambda func: None @call_if_true(re.match(rname=(.*))) def set_name(m): name = m.group(1).strip() @call_if_true(re.match(rid=(.*))) def set_id(m): id = m.group(1).strip() @call_if_true(re.match(rphone=(.*))) def set_phone(m): phone = m.group(1).strip() This decorator might be more to the point: def call_if_match(regexp): m = re.match(regexp) if m: return lambda func: func(m) return lambda func: None These have the drawback of being a little dense, and the functions can't rebind variables in the caller's local namespace, but it is clever. P.S. I don't recommend using it. Carl Banks -- http://mail.python.org/mailman/listinfo/python-list
Re: Return value of an assignment statement?
Jeff Schwab [EMAIL PROTECTED] wrote: a += b Whether a refers to the same object before and after that statement depends on what type of object it referred to before the statement. Yes but the rule followed by the builtin types is pretty simple: if 'a' can still refer to the same object then it does. Immutable objects make this impossible most of the time (unless 'b' is 0, (), or similar), and there may be other exceptions I've missed, but this is the general principle, so mutable objects will mutate and immutable objects won't. Whether the same rule is followed outside the core is, of course, up to the individual developers. -- http://mail.python.org/mailman/listinfo/python-list
Re: Return value of an assignment statement?
Carl Banks [EMAIL PROTECTED] writes: import re pat = re.compile('some pattern') if m = pat.match(some_string): do_something(m) ... Don't be ridiculous. Assignment operators are maybe one of the worst things in existence, but this particular use case (running a sequence of tests like the above) is perfectly useful and good. I've been known to do stuff like: class xmatch: def set(self, v): self.v = v return v then: s = xmatch() if s.set(pat.match(some_string)): do_something(s.v) elif s.set(pat.match(other_string)): do_other_thing(s.v) ... -- http://mail.python.org/mailman/listinfo/python-list
Re: Return value of an assignment statement?
Carl Banks [EMAIL PROTECTED] wrote: Some Pythonistas will swear to their grave and back that should be done by factoring out the tests into a list and iterating over it, and NO OTHER WAY WHATSOEVER, but I don't buy it. That's a lot of boilerplate--the very thing Python is normally so good at minimizing-- when it might not be needed. It would be the right thing for a complex, pluggable, customizable input filter; but is rarely a better solution for a simple text processing script. I'll swear to my grave that there is always a better way than a lot of nested regex conditions, and that may or may not involve a list but there are plenty of other ways. That's why this is such a hard question to answer definitively: every situatiuon has a different answer. Quick, at a glance, which code snippet will you understand faster (pretend you know Perl): if (/name=(.*)/) { $name = chop(\1); } elsif (/id=(.*)/) { $id = chop(\1); } elsif (/phone=(.*)/) { $phone = chop(\1); } I get a headache with that: somehow I have to either magically know which variable out of name, id and phone exists or I have to set all 3 variables with suitable defaults for the unset ones. Perl I believe will allow access to unset variables but Python doesn't, so it looks like I'll have a bunch of extra code to make sure they all get set. vs. PATTERN = re.compile('(?:name=(.*))|(?:id=(.*))|(?:phone=(.*))') ... m = PATTERN.match(argument) if not m: raise FormatError('bad input: %s' % argument) name, id, phone = m.groups() oops, not so much extra code to set them after all. Actually in practice I'd probably use something more like: PATTERN = re.compile('''(?:name=(?Pname.*)) |(?:id=(?Pid.*)) |(?:phone=(?Pphone.*))''', re.VERBOSE) ... m = PATTERN.match(argument) if not m: raise FormatError('bad input: %s' % argument) values = m.groupdict() as I find named groups much less error prone. -- http://mail.python.org/mailman/listinfo/python-list
Re: Return value of an assignment statement?
Jeff Schwab a écrit : [EMAIL PROTECTED] wrote: (snip) Explicitely using list.extend would make things clearer: def invoke_some_fct(parent): parent.x.extend(['world']) Whether you use += or extend has nothing to do with it. Mmm... Really ? You omitted the relevant part. Using extend, it would look like: y = parent.x y.extend(['world']) The confusing part is that performing an operation on y may or may not alter parent.x, depending on whether the initial type of parent.x is immutable. given that Python doesn't copy anything unless explicitelly asked for, the y = parent.x statement has the very clear semantic of making y an alias of parent.x. Mutability has nothing to do with it, except for the fact that if parent.x is immutable there's indeed no way to mutate it. If parent.x is immutable, y is a copy of the value represented by parent.x, No, by no way. class Parent(object): pass ... p = Parent() p.x = aaa + bbb # a string that won't be interned y = p.x y is p.x True y is *not* a copy of x, it is another name bound to the very same object. and modifying y has not effect on the value of parent.x. Your problem is with the semantic of modifying. In Python, (re)binding a name and mutating an object are two very distinct things. If (the object referenced by) y is immutable, you *can not* modify (= mutate) it. Period. And if you *rebind* y, this *won't* affect p.x, whether it's mutable or not: p = Parent() p.x = ['allo'] y = p.x y is p.x True y = ['la terre'] y ['la terre'] p.x ['allo'] y is p.x False IOW - and while, you're right about this, I skipped the part that trouble you, that is the aliasing of parent.x -, the observation that using list.extend (that is, clearly a mutator method call) instead of augmented assignment which *looks like* it's rebinding y (and would effectively rebind it if y was immutable). FWIW, it's IMHO a real wart - given Python's pretention at readability - that augmented assignement has been implemented that way for lists. If (OTOH) parent.x is mutable, then x and y are really references to the same object, and modifications to that object via y can be observed via x. In C, you use pointers to get this effect. Not quite the same thing. C variables are boxes (containing values), with pointer's values being the coords of another box, while Python's 'variables' are only labels on objects - they *never* 'contains' anything. (FWIW, someone recently posted a link to a very good explanation of this, but I don't have it under hand right now - could someone help ?) With pointers, a function can modify the content of a box defined in the caller's scope. This is not something you can do in Python - that is, rebinding a formal parameter to a different object withing a function won't affect the bindings in the caller's scope: def rebinder(x): print before: x = %s (id: %s) % (x, id(x)) x = ['bar'] print after: x = %s (id: %s) % (x, id(x)) def caller(): a = ['foo'] print before: a = %s (id: %s) % (a, id(a)) rebinder(a) print after: a = %s (id: %s) % (a, id(a)) caller() Now there's no reason to feel nervous about this. All you have to remember is that Python never copy anything unless explicitely asked for. It's not that simple. After a statement like: a = b Whether a and b denote the same object depends on what kind of object b represented in the first place. No. You can bet your life on this : after this statement, a and b are two labels for the very same object, *always*, *whatever* the type of b. Now this is a very frequent cause of confusion for C/C++ programmers, and it has been explained again and again here - usually far better than I just did, so you may want to google for this. HTH -- http://mail.python.org/mailman/listinfo/python-list
Re: Return value of an assignment statement?
On Thu, 21 Feb 2008 16:23:23 -0800, Jeff Schwab wrote: Steve Holden wrote: [...] if m = pat.match(some_string): do_something(m) Yep, this is exactly what I am (was) trying to do. Oh well Any clever ideas on this front? The syntax is the way it is precisely to discourage that kind of clever idea. Of course, people nevertheless manage to work around the restriction to try and make their Python read like some other language they are more familiar with, and most of the time they get away with it. The fat remains that in programming there *is* such a thing as being too clever, and Python's syntax deliberately discourages that. This isn't clever. It's what most of us were taught, from the beginning, was best practice. In some languages (including C and C++) the above is extremely common and perfectly acceptable. Speak for yourself. *I* was never taught to abuse assignment by making it an expression, and in the languages I have used, it isn't. I'm sorry that your programming ability has been permanently harmed by learning C at too early an age, but please don't imagine the rest of us suffer from this disability. *wink* -- Steven -- http://mail.python.org/mailman/listinfo/python-list
Re: Return value of an assignment statement?
On Fri, 22 Feb 2008 08:12:56 +, Marc 'BlackJack' Rintsch wrote: A variable in programming languages is composed of a name, a memory location, possibly a type and a value. In C-like languages, where you put values in named and typed boxes, the memory location and type are attached to the name. In Python both belong to the value. But Python objects don't have names, so by your own definition, they aren't variables. Names are associated with namespaces, not objects. A name must have one and only one object bound to it at any one time; objects on the other hand can be bound to one name, or no name, or a thousand names. The object itself has no way of knowing what names it is bound to, if any. Or, to put it another way... Python doesn't have variables. -- Steven -- http://mail.python.org/mailman/listinfo/python-list
Re: Return value of an assignment statement?
On Fri, 22 Feb 2008 00:45:59 -0800, Carl Banks wrote: On Feb 21, 6:52 pm, Steve Holden [EMAIL PROTECTED] wrote: mrstephengross wrote: What you can't do (that I really miss) is have a tree of assign-and-test expressions: import re pat = re.compile('some pattern') if m = pat.match(some_string): do_something(m) Yep, this is exactly what I am (was) trying to do. Oh well Any clever ideas on this front? The syntax is the way it is precisely to discourage that kind of clever idea. Don't be ridiculous. Assignment operators are maybe one of the worst things in existence, but this particular use case (running a sequence of tests like the above) is perfectly useful and good. I don't understand your reasoning. If assignment operators are so terrible, why do you think the terribleness disappears in this specific case? The above idiom leads to one of the most common errors in C code: writing = when you mean ==. Running a sequence of tests isn't immune to that problem, it's especially vulnerable to it. Compare the suggested pseudo-Python code: pat = re.compile('some pattern') if m = pat.match(some_string): do_something(m) with the actual Python code: pat = re.compile('some pattern') m = pat.match(some_string) if m: do_something(m) The difference is exactly one newline plus one extra reference to the name m. And this is a problem? Some Pythonistas will swear to their grave and back that should be done by factoring out the tests into a list and iterating over it, and NO OTHER WAY WHATSOEVER, but I don't buy it. Well, putting a sequence of tests into a list is the natural way to deal with a sequence of tests. What else would you do? That's a lot of boilerplate What boilerplate are you talking about? --the very thing Python is normally so good at minimizing-- when it might not be needed. It would be the right thing for a complex, pluggable, customizable input filter; but is rarely a better solution for a simple text processing script. Huh? Quick, at a glance, which code snippet will you understand faster (pretend you know Perl): if (/name=(.*)/) { $name = chop(\1); } elsif (/id=(.*)/) { $id = chop(\1); } elsif (/phone=(.*)/) { $phone = chop(\1); } vs. def set_phone_number(m): phone = m.group(1).strip() def set_id(m): id = m.group(1).strip() def set_name(m): name = m.group(1).strip() _line_tests = [ (rphone=(.*), set_phone_number), (rname=(.*), set_name), (rid=(.*), set_id), ] for pattern,func in _line_tests: m = re.match(pattern,line) if m: func(m) At this small scale, and probably at much larger scales too, the Perl example blows the Python example out of the water in terms of readability. And that's counting Perl's inherent unreadableness. Why would you do that test in such an overblown fashion, then try to pretend it is an apples-and-apples comparison with the Perl code? It doesn't even work: you have three functions that set a local name, then throw it away when they return. Pretending I understand Perl, here's a fairer, more direct translation of the Perl code: name, id, phone = [None]*3 # Closest thing to an unset variable in Perl. name = re.match(rname=(.*), line) if name: name = name.group(1).strip() else: id = re.match(rid=(.*), line) if id: id = id.group(1).strip() else: phone = re.match(rphone=(.*), line) if phone: phone = phone.group(1).strip() Six lines for Perl against nine for Python, eight if you dump the unset line. Hardly a big difference. The main difference is that Python's handling of regexes is a little more verbose, and that the indentation is compulsory. But here's a better way to do the same test: tests = [ (rname=(.*), 'name'), (rid=(.*), 'id'), (rphone=(.*), 'phone')] for (test, name) in tests: m = re.match(t, line) if m: globals()[name] = m.group(1).strip() break Down to seven lines, or six if the I didn't split the tests over two lines. Here's an even better way: tests = [ name, id, phone] for t in tests: m = re.match(t + r=(.*), line) if m: globals()[t] = m.group(1).strip() break Six lines for Perl, six for Python, and the Python version is far more readable. Perl's treatment of assignment as an operator tempts the programmer to write quick-and-dirty code. Python discourages that sort of behaviour, and encourages programmers to factor their code in a structured way. That's a feature, not a bug. -- Steven -- http://mail.python.org/mailman/listinfo/python-list
Re: Return value of an assignment statement?
On Fri, 22 Feb 2008 12:32:10 +, Steven D'Aprano wrote: On Fri, 22 Feb 2008 08:12:56 +, Marc 'BlackJack' Rintsch wrote: A variable in programming languages is composed of a name, a memory location, possibly a type and a value. In C-like languages, where you put values in named and typed boxes, the memory location and type are attached to the name. In Python both belong to the value. But Python objects don't have names, so by your own definition, they aren't variables. Exactly! Names aren't variables. The unit of a name, an address, and a value are a variable. Names are associated with namespaces, not objects. A name must have one and only one object bound to it at any one time; What is a binding when it's not an association between a name and an object!? So names are associated with objects. There are no names without objects in Python. If a name is not bound to any object, how could the name exist? That would be like a dangling pointer, a beast that doesn't exists in Python. nitpickOkay there are local names that are known and therefore somehow exist before they get bound, but that's IMHO an implementation detail.nitpick objects on the other hand can be bound to one name, or no name, or a thousand names. The object itself has no way of knowing what names it is bound to, if any. Or, to put it another way... Python doesn't have variables. It has. You just can't substitute the term name with variable and expect it to behave like in C. A variable is not just the name but also the value and the storage space and how those are connected. Ciao, Marc 'BlackJack' Rintsch -- http://mail.python.org/mailman/listinfo/python-list
Re: Return value of an assignment statement?
On Feb 22, 9:58 am, Steven D'Aprano [EMAIL PROTECTED] cybersource.com.au wrote: On Fri, 22 Feb 2008 00:45:59 -0800, Carl Banks wrote: On Feb 21, 6:52 pm, Steve Holden [EMAIL PROTECTED] wrote: mrstephengross wrote: What you can't do (that I really miss) is have a tree of assign-and-test expressions: import re pat = re.compile('some pattern') if m = pat.match(some_string): do_something(m) Yep, this is exactly what I am (was) trying to do. Oh well Any clever ideas on this front? The syntax is the way it is precisely to discourage that kind of clever idea. Don't be ridiculous. Assignment operators are maybe one of the worst things in existence, but this particular use case (running a sequence of tests like the above) is perfectly useful and good. I don't understand your reasoning. If assignment operators are so terrible, why do you think the terribleness disappears in this specific case? I don't. The assignment operator is terrible but the idiom itself isn't. [snip narrowly applicable counterexamples that don't really mean anything because they're too narrow] Perl's treatment of assignment as an operator tempts the programmer to write quick-and-dirty code. (The perl example wasn't using an assignment operator.) Python discourages that sort of behaviour, and encourages programmers to factor their code in a structured way. That's a feature, not a bug. The set-and-test idiom is not necessarily quick and dirty, and for many things it's more readable and a lot easier to follow than any of indirect methods that are proposed. The fact that sometimes an assignment operator is used to do this doesn't change the usefulness of the idiom itself. It can be done without assignment expressions. I gave a hypothetical syntax for how it might be done in Python without them. I can't help but to think that a lot of people's distaste for this natural way to write certain logic is simply defensiveness about one minor little thing that Python doesn't support (without workarounds). Carl Banks -- http://mail.python.org/mailman/listinfo/python-list
Re: Return value of an assignment statement?
Marc 'BlackJack' Rintsch wrote: On Fri, 22 Feb 2008 12:32:10 +, Steven D'Aprano wrote: On Fri, 22 Feb 2008 08:12:56 +, Marc 'BlackJack' Rintsch wrote: A variable in programming languages is composed of a name, a memory location, possibly a type and a value. In C-like languages, where you put values in named and typed boxes, the memory location and type are attached to the name. In Python both belong to the value. But Python objects don't have names, so by your own definition, they aren't variables. Exactly! Names aren't variables. The unit of a name, an address, and a value are a variable. Names are associated with namespaces, not objects. A name must have one and only one object bound to it at any one time; What is a binding when it's not an association between a name and an object!? So names are associated with objects. There are no names without objects in Python. If a name is not bound to any object, how could the name exist? That would be like a dangling pointer, a beast that doesn't exists in Python. nitpickOkay there are local names that are known and therefore somehow exist before they get bound, but that's IMHO an implementation detail.nitpick objects on the other hand can be bound to one name, or no name, or a thousand names. The object itself has no way of knowing what names it is bound to, if any. Or, to put it another way... Python doesn't have variables. It has. You just can't substitute the term name with variable and expect it to behave like in C. A variable is not just the name but also the value and the storage space and how those are connected. Does ... Doesn't ... Does so!. You guys are merely arguing about what you want to call the Python assignment semantics you both understand perfectly well. This isn't going to help anyone. The fact of the matter is that when a Python name is bound to a value the value is normally created in heap storage (with a few exceptions like the pre-allocated objects such as None and the small integers, but *never* directly in the namespace in which the name is being bound), and the name is associated with a reference to the value. I've said before that Python names are very similar to automatically dereferenced pointer variables, and I suppose the same old arguments will be trotted out against that utterance now I've said it again. But for the purposes of comprehension, particularly by C and C++ programmers who haven't come across this particular semantic before it should server to aid comprehension. The fact that objects exist independent of the dynamically created scopes of function calls and the like is precisely what stops Python from suffering the same out-of-scope (dangling) pointer issues that C++ is famous for. The fact remains that name binding in Python (and binding to container items too) doesn't return a value, and bindings were deliberately not allowed as a term in a broader expression to avoid some common programming errors. regards Steve -- Steve Holden+1 571 484 6266 +1 800 494 3119 Holden Web LLC http://www.holdenweb.com/ -- http://mail.python.org/mailman/listinfo/python-list
Re: Return value of an assignment statement?
Carl Banks wrote: On Feb 21, 6:52 pm, Steve Holden [EMAIL PROTECTED] wrote: mrstephengross wrote: What you can't do (that I really miss) is have a tree of assign-and-test expressions: import re pat = re.compile('some pattern') if m = pat.match(some_string): do_something(m) Yep, this is exactly what I am (was) trying to do. Oh well Any clever ideas on this front? The syntax is the way it is precisely to discourage that kind of clever idea. Don't be ridiculous. Assignment operators are maybe one of the worst things in existence, but this particular use case (running a sequence of tests like the above) is perfectly useful and good. Some Pythonistas will swear to their grave and back that should be done by factoring out the tests into a list and iterating over it, and NO OTHER WAY WHATSOEVER, but I don't buy it. That's a lot of boilerplate--the very thing Python is normally so good at minimizing-- when it might not be needed. It would be the right thing for a complex, pluggable, customizable input filter; but is rarely a better solution for a simple text processing script. Quick, at a glance, which code snippet will you understand faster (pretend you know Perl): if (/name=(.*)/) { $name = chop(\1); } elsif (/id=(.*)/) { $id = chop(\1); } elsif (/phone=(.*)/) { $phone = chop(\1); } vs. def set_phone_number(m): phone = m.group(1).strip() def set_id(m): id = m.group(1).strip() def set_name(m): name = m.group(1).strip() _line_tests = [ (rphone=(.*), set_phone_number), (rname=(.*), set_name), (rid=(.*), set_id), ] for pattern,func in _line_tests: m = re.match(pattern,line) if m: func(m) At this small scale, and probably at much larger scales too, the Perl example blows the Python example out of the water in terms of readability. And that's counting Perl's inherent unreadableness. I'm supposed to overlook the fact that your example in Python omits the untested it clearly deserves, I take it? I'm not sure what you are trying to do with the assignments inside the function body. The brevity of the Perl has something to commend it, but I am always suspicious about whether algorithms like that should really be data driven. It's all too easy to add further tests as new field possibilities are added. It's also unpleasant in that it leaves two variables in an undetermined state. Let's assume that your Python functions were correctly assigning to attributes of some object that was being passed in or global, at least then it would be possible to add an else condition to each iteration to set the attribute's default value somehow. So I think your example is perhaps not the best one you could have chosen to make your case. I will admit that idiomatic usages are acceptable ways to perform common tasks, but I still think that Guido's decision to eschew assignments as expression terms is a sound one, and one that encourages better program construction. Hey, call me (or my assertions) ridiculous if you want. It remains that allowing such terms will inevitably lead to hard-to-debug confusion between assignment and equality testing once the difference becomes a single equals sign. If it were a priority, Python could support this set-and-test idiom, and without an assignment operator. (Notice Perl doesn't use assignment operator here.) For example, a syntax like this (where the scope of m is local to the if-condition and the body of the if- statement: if m where m = re.match(rname=(.*),line): name = m.group(1).strip() elif m where m = re.match(rid=(.*),line): id = m.group(1).strip() elif m where m = re.match(rphone=(.*),line): phone = m.group(1).strip() [I'll presume you've already established default values for name, id and phone just to quiet the alarms ringing in the background]. Still looks to me like it might be better data-driven with a setattr() in there somewhere. As far as I can see all this would achieve would be to limit the scope of the assignment, and I don't really see what advantage that provides. This won't happen because the set-and-test idiom is relatively minor and not deemed worthy of syntax support. But if it were there, there'd really be nothing clever about it. Note also that I'm not saying an experienced programmer can't get these things right. But at any given time half the programmers in the world are newbies, and Python tries to help them by steering them in safer directions. Maybe we could allow it if you had a digital certificate asserting that you'd passed your metaclass abuse test ... 0.75 wink regards Steve -- Steve Holden+1 571 484 6266 +1 800 494 3119 Holden Web LLC http://www.holdenweb.com/ -- http://mail.python.org/mailman/listinfo/python-list
Re: Return value of an assignment statement?
On Fri, 22 Feb 2008 08:19:07 -0800, Carl Banks wrote: (The perl example wasn't using an assignment operator.) Hmmm... I see. Obviously I didn't pretend to understand Perl well enough. (I assume you're ignoring the assignments $name = chop(\1) etc. Fair enough.) [...] I can't help but to think that a lot of people's distaste for this natural way to write certain logic is simply defensiveness about one minor little thing that Python doesn't support (without workarounds). But Python certainly does support set-and-test. You just have to separate the set from the test with a newline: m = re.match(rname=(.*),line) # set if m: # test name = m.group(1).strip() This does the same thing as your proposed syntax if m where m = re.match(rname=(.*),line): name = m.group(1).strip() except that it doesn't create a new scope. I'm not sure that the benefit of having a new scope is worth the new keyword. Maybe it is, maybe it isn't. I think I have a better idea of what you are trying to say. Despite first impressions, you weren't defending the proposed assign-and-test idiom suggested by Stephen Gross: pat = re.compile('some pattern') if m = pat.match(some_string): # doesn't work in Python do_something(m) on account of it needing an assignment expression, which is Bad. But you were defending the principle of set-and-test, if we can use something other than an assignment expression to do the set. E.g. Perl's magic syntax if /pattern/ { } (everything in Perl is magic syntax), or your proposed if m where m = expression. Okay, I can agree with that, particularly since Python already supports it using the plain old boring, old fashioned idiom of assign, then test. -- Steven -- http://mail.python.org/mailman/listinfo/python-list
Re: Return value of an assignment statement?
In article [EMAIL PROTECTED], Bruno Desthuilliers [EMAIL PROTECTED] wrote: FWIW, it's IMHO a real wart - given Python's pretention at readability - that augmented assignement has been implemented that way for lists. This was debated extensively when augmented assignment was created, and it was decided that practicality beat purity. It's just too convenient to be able to write L += ['foo'] without rebinding L. -- Aahz ([EMAIL PROTECTED]) * http://www.pythoncraft.com/ All problems in computer science can be solved by another level of indirection. --Butler Lampson -- http://mail.python.org/mailman/listinfo/python-list
Re: Return value of an assignment statement?
In article [EMAIL PROTECTED], Jeff Schwab [EMAIL PROTECTED] wrote: Aahz wrote: In article [EMAIL PROTECTED], Jeff Schwab [EMAIL PROTECTED] wrote: [EMAIL PROTECTED] wrote: There's nothing like a variable storing anything in Python. All you have are names to (references to) objects binding in a namespace. Now the fact is that some types are mutable and other are not. In your above example, the augmented assignment does *not* rebind a, but invoke a.extend(). With integers, it would have rebind a. So while your observation is exact, your interpretation is wrong !-) Thank you for the clarification. For some reason, I had it in my head that ints were packed directly into the C structures that represent Python variables, in the same (union?) member that otherwise would store a pointer. Notice very very carefully that Bruno is not using variable. Many expert Python programmers strongly prefer to talk about names instead of variables (especially when explaining the Python object model) precisely because using variable leads to incorrect expectations. http://starship.python.net/crew/mwh/hacks/objectthink.html So what is the variable? Or is Python the first HLL I've ever heard of that didn't have variables? Whether Python has variables depends on your perspective. Python certainly does *not* have variables with anything like the semantics of C/C++ variables. For that reason, it's often convenient to shift the vocabulary to avoid misunderstading. However, the vast majority of Python programmers do use variable in casual conversation (I certainly do); it's only when trying to discuss the Python object model that there's a strong tendency to switch to using names. -- Aahz ([EMAIL PROTECTED]) * http://www.pythoncraft.com/ All problems in computer science can be solved by another level of indirection. --Butler Lampson -- http://mail.python.org/mailman/listinfo/python-list
Re: Return value of an assignment statement?
George Sakkis wrote: On Feb 22, 12:26 am, Jeff Schwab [EMAIL PROTECTED] wrote: On the other hand, a = b does always the same thing; unlike C++, '=' is not an operator and therefore it cannot be overriden by the class of 'a'. Not an operator? Then what is it? In this context, it's just the token used for the assignment statement. In short, if 'a' is an identifier, the statement means bind the name 'a' to the object 'b' (in the local or global namespace). It doesn't say anything about memory allocation, initialization or copying. The only case where assigning an identifier affects memory is the following [1]: The name is rebound if it was already bound. This may cause the reference count for the object previously bound to the name to reach zero, causing the object to be deallocated and its destructor (if it has one) to be called. [1] http://docs.python.org/ref/assignment.html OK, thanks for trying to make it clear. I'm about through with this discussion, but FWIW, this is a real gotcha for me and many others. This is a case where Python does not do what many programmers expect, and it at least takes some getting used-to. -- http://mail.python.org/mailman/listinfo/python-list
Re: Return value of an assignment statement?
On Fri, 22 Feb 2008 11:00:17 -0800, Aahz wrote: In article [EMAIL PROTECTED], Bruno Desthuilliers [EMAIL PROTECTED] wrote: FWIW, it's IMHO a real wart - given Python's pretention at readability - that augmented assignement has been implemented that way for lists. This was debated extensively when augmented assignment was created, and it was decided that practicality beat purity. It's just too convenient to be able to write L += ['foo'] without rebinding L. *scratches head* Wouldn't L.append('foo') or L.extend(['foo']) be even more convenient, and have perfectly obvious behaviour without leading to the confusion of augmented assignments? Personally, I think the confusion of augmented assignments is not worth the benefit of saving typing a couple of characters. I think Guido's first decision, to leave += etc out of the language, was the right decision. -- Steven -- http://mail.python.org/mailman/listinfo/python-list
Re: Return value of an assignment statement?
Steven D'Aprano [EMAIL PROTECTED] writes: Personally, I think the confusion of augmented assignments is not worth the benefit of saving typing a couple of characters. I think Guido's first decision, to leave += etc out of the language, was the right decision. It quite helpful to be able to say foo['bar'+lookup(baz)][blob(a)+frob(b)] += 1 without having to split it into separate statements to avoid repeating the function calls and their possible side effects. -- http://mail.python.org/mailman/listinfo/python-list
Re: Return value of an assignment statement?
On Feb 22, 1:16 pm, Steven D'Aprano [EMAIL PROTECTED] cybersource.com.au wrote: On Fri, 22 Feb 2008 08:19:07 -0800, Carl Banks wrote: (The perl example wasn't using an assignment operator.) Hmmm... I see. Obviously I didn't pretend to understand Perl well enough. (I assume you're ignoring the assignments $name = chop(\1) etc. Fair enough.) [...] I can't help but to think that a lot of people's distaste for this natural way to write certain logic is simply defensiveness about one minor little thing that Python doesn't support (without workarounds). But Python certainly does support set-and-test. You just have to separate the set from the test with a newline: A single set-and-test operation is not equivalent to two consecutive operations, set and test. m = re.match(rname=(.*),line) # set if m: # test name = m.group(1).strip() For a single set-and-test the inconvenience is minimal, but stack a bunch of them together (even more if there are 'else' clauses in the mix) and the syntactic inefficiency becomes quite visible. George -- http://mail.python.org/mailman/listinfo/python-list
Return value of an assignment statement?
Hi all. In C, an assignment statement returns the value assigned. For instance: int x int y = (x = 3) In the above example, (x=3) returns 3, which is assigned to y. In python, as far as I can tell, assignment statements don't return anything: y = (x = 3) The above example generates a SyntaxError. Is this correct? I just want to make sure I've understood the semantics. Thanks, --Steve -- http://mail.python.org/mailman/listinfo/python-list
Re: Return value of an assignment statement?
On Feb 21, 1:43 pm, mrstephengross [EMAIL PROTECTED] wrote: Hi all. In C, an assignment statement returns the value assigned. For instance: int x int y = (x = 3) In the above example, (x=3) returns 3, which is assigned to y. In python, as far as I can tell, assignment statements don't return anything: y = (x = 3) The above example generates a SyntaxError. Is this correct? I just want to make sure I've understood the semantics. Thanks, --Steve That's true, and I am happy that they decided to make that a syntax error. -- http://mail.python.org/mailman/listinfo/python-list
Re: Return value of an assignment statement?
mrstephengross wrote: Hi all. In C, an assignment statement returns the value assigned. For instance: int x int y = (x = 3) In the above example, (x=3) returns 3, which is assigned to y. In python, as far as I can tell, assignment statements don't return anything: y = (x = 3) The above example generates a SyntaxError. Is this correct? I just want to make sure I've understood the semantics. Yes, but there is valid syntax for the common case you mentioned: y = x = 3 What you can't do (that I really miss) is have a tree of assign-and-test expressions: import re pat = re.compile('some pattern') if m = pat.match(some_string): do_something(m) else if m = pat.match(other_string): do_other_thing(m) else: do_default_thing() -- http://mail.python.org/mailman/listinfo/python-list
Re: Return value of an assignment statement?
On Feb 21, 2:43 pm, mrstephengross [EMAIL PROTECTED] wrote: Hi all. In C, an assignment statement returns the value assigned. For instance: int x int y = (x = 3) In the above example, (x=3) returns 3, which is assigned to y. In python, as far as I can tell, assignment statements don't return anything: y = (x = 3) The above example generates a SyntaxError. Is this correct? I just want to make sure I've understood the semantics. Thanks, --Steve x = y = 1 print x, y --output:-- 1 1 With parentheses, it looks like python thinks you are trying to do a boolean == inside the parentheses. It's the same error you get if you write: if x = y: print 'yes' -- http://mail.python.org/mailman/listinfo/python-list
Re: Return value of an assignment statement?
On Feb 21, 1:48 pm, John Henry [EMAIL PROTECTED] wrote: On Feb 21, 1:43 pm, mrstephengross [EMAIL PROTECTED] wrote: Hi all. In C, an assignment statement returns the value assigned. For instance: int x int y = (x = 3) In the above example, (x=3) returns 3, which is assigned to y. In python, as far as I can tell, assignment statements don't return anything: y = (x = 3) The above example generates a SyntaxError. Is this correct? I just want to make sure I've understood the semantics. Thanks, --Steve That's true, and I am happy that they decided to make that a syntax error. BTW: The less obvious issues when coming from the C world are Python syntax like these: y = x = 3 a = 4 y = x = a print x,y a = 5 print x,y -- http://mail.python.org/mailman/listinfo/python-list
Re: Return value of an assignment statement?
What you can't do (that I really miss) is have a tree of assign-and-test expressions: import re pat = re.compile('some pattern') if m = pat.match(some_string): do_something(m) Yep, this is exactly what I am (was) trying to do. Oh well Any clever ideas on this front? --Steve -- http://mail.python.org/mailman/listinfo/python-list
Re: Return value of an assignment statement?
John Henry wrote: On Feb 21, 1:48 pm, John Henry [EMAIL PROTECTED] wrote: On Feb 21, 1:43 pm, mrstephengross [EMAIL PROTECTED] wrote: Hi all. In C, an assignment statement returns the value assigned. For instance: int x int y = (x = 3) In the above example, (x=3) returns 3, which is assigned to y. In python, as far as I can tell, assignment statements don't return anything: y = (x = 3) The above example generates a SyntaxError. Is this correct? I just want to make sure I've understood the semantics. Thanks, --Steve That's true, and I am happy that they decided to make that a syntax error. BTW: The less obvious issues when coming from the C world are Python syntax like these: y = x = 3 a = 4 y = x = a print x,y a = 5 print x,y That's the same behavior I would expect in C, on the grounds that C assignments do bit-wise copies. What I found confusing at first was that the same variable will either directly store or merely refer to an object, depending on the type of the object: a = [ 'hello' ] y = x = a a += [ 'world' ] print x, y ['hello', 'world'] ['hello', 'world'] -- http://mail.python.org/mailman/listinfo/python-list
Re: Return value of an assignment statement?
mrstephengross wrote: What you can't do (that I really miss) is have a tree of assign-and-test expressions: import re pat = re.compile('some pattern') if m = pat.match(some_string): do_something(m) Yep, this is exactly what I am (was) trying to do. Oh well Any clever ideas on this front? I worked around it by defining a separate thigamabob with a result property. A method of the thigamabob internally performs the assignment, and returns a boolean result. The body of each branch in the tree can then retrieve the result object from the thigamabob. Here's an example hard-coded to match strings against patterns, but I think the idea should be extensible to other kinds of assign-and-test situations. # Just for the sake of this post. def do_something(m): pass def do_other_thing(m): pass def do_default_thing(): pass import re class Matcher(object): def __call__(self, pattern, string): self.result = pattern.match(string) if __name__ == '__main__': pat = re.compile('some pattern') match = Matcher() if match(pat, 'a'): do_something(match.result) elif match(pat, 'b'): do_other_thing(match.result) else: do_default_thing() -- http://mail.python.org/mailman/listinfo/python-list
Re: Return value of an assignment statement?
On Feb 21, 2:06 pm, Jeff Schwab [EMAIL PROTECTED] wrote: John Henry wrote: On Feb 21, 1:48 pm, John Henry [EMAIL PROTECTED] wrote: On Feb 21, 1:43 pm, mrstephengross [EMAIL PROTECTED] wrote: Hi all. In C, an assignment statement returns the value assigned. For instance: int x int y = (x = 3) In the above example, (x=3) returns 3, which is assigned to y. In python, as far as I can tell, assignment statements don't return anything: y = (x = 3) The above example generates a SyntaxError. Is this correct? I just want to make sure I've understood the semantics. Thanks, --Steve That's true, and I am happy that they decided to make that a syntax error. BTW: The less obvious issues when coming from the C world are Python syntax like these: y = x = 3 a = 4 y = x = a print x,y a = 5 print x,y That's the same behavior I would expect in C, on the grounds that C assignments do bit-wise copies. What I found confusing at first was that the same variable will either directly store or merely refer to an object, depending on the type of the object: a = [ 'hello' ] y = x = a a += [ 'world' ] print x, y ['hello', 'world'] ['hello', 'world'] Yep. Took me a while to realize there is mutable objects, and non- mutable objects. To be honest, I am still not too comfortable about it. For instance, I still get nervous for code like: def invoke_some_fct(parent): y = parent.x y += [ 'world' ] print y, parent.x class abc: def __init__(self): self.x=[ 'hello' ] invoke_some_fct(self) print self.x hw = abc() -- http://mail.python.org/mailman/listinfo/python-list
Re: Return value of an assignment statement?
Hi all. In C, an assignment statement returns the value assigned. No. C doesn't have an assignment statement. Instead, in C, assignment is an expression (just like a binary operation or a function call); that expression evaluates to the value assigned (i.e. the result is the value, the assignment is just a side-effect). What you consider the assignment statement is actually an expression statement, of the syntax expression semicolon So x = y; f(); 3+4; are all the same kind of statement. In python, as far as I can tell, assignment statements don't return anything: Right - that's because they are statements. No statement returns a value - except for the return statement, of course, but it doesn't return it in the sense that you could write foo = return 44 Because of the confusing meaning of return, I find it better to say that expressions evaluate to a value, not that they return a value. The above example generates a SyntaxError. Is this correct? I just want to make sure I've understood the semantics. Please try to study more on the difference between expressions and statements. Regards, Martin P.S. Just to confuse matters: GNU C also has statement expressions, of the form ({ int y = foo (); int z; if (y 0) z = y; else z = - y; z; }) These are expressions, but allow the expressiveness of statements (including variable declarations) -- http://mail.python.org/mailman/listinfo/python-list
Re: Return value of an assignment statement?
Jeff Schwab [EMAIL PROTECTED] wrote in message news:[EMAIL PROTECTED] | That's the same behavior I would expect in C, on the grounds that C | What I found confusing at first was | that the same variable will either directly store or merely refer to an | object, depending on the type of the object: Since names and collection slots always refer to objects, I find the above confusing. Can you clarify what difference you percieve? tjr -- http://mail.python.org/mailman/listinfo/python-list
Re: Return value of an assignment statement?
On 21 fév, 23:19, John Henry [EMAIL PROTECTED] wrote: On Feb 21, 2:06 pm, Jeff Schwab [EMAIL PROTECTED] wrote: John Henry wrote: On Feb 21, 1:48 pm, John Henry [EMAIL PROTECTED] wrote: On Feb 21, 1:43 pm, mrstephengross [EMAIL PROTECTED] wrote: Hi all. In C, an assignment statement returns the value assigned. For instance: int x int y = (x = 3) In the above example, (x=3) returns 3, which is assigned to y. In python, as far as I can tell, assignment statements don't return anything: y = (x = 3) The above example generates a SyntaxError. Is this correct? I just want to make sure I've understood the semantics. Thanks, --Steve That's true, and I am happy that they decided to make that a syntax error. BTW: The less obvious issues when coming from the C world are Python syntax like these: y = x = 3 a = 4 y = x = a print x,y a = 5 print x,y That's the same behavior I would expect in C, on the grounds that C assignments do bit-wise copies. What I found confusing at first was that the same variable will either directly store or merely refer to an object, depending on the type of the object: a = [ 'hello' ] y = x = a a += [ 'world' ] print x, y ['hello', 'world'] ['hello', 'world'] Yep. Took me a while to realize there is mutable objects, and non- mutable objects. To be honest, I am still not too comfortable about it. For instance, I still get nervous for code like: def invoke_some_fct(parent): y = parent.x y += [ 'world' ] print y, parent.x class abc: def __init__(self): self.x=[ 'hello' ] invoke_some_fct(self) print self.x Explicitely using list.extend would make things clearer: def invoke_some_fct(parent): parent.x.extend(['world']) Now there's no reason to feel nervous about this. All you have to remember is that Python never copy anything unless explicitely asked for. -- http://mail.python.org/mailman/listinfo/python-list
Re: Return value of an assignment statement?
What you can't do (that I really miss) is have a tree of assign-and-test expressions: import re pat = re.compile('some pattern') if m = pat.match(some_string): do_something(m) else if m = pat.match(other_string): do_other_thing(m) else: do_default_thing() What you want is: for astring, afunc in ((some_string, do_something), (other_string, do_other_thing)): m = pat.match(astring) if m: afunc(m) break else: do_default_thing() -- http://mail.python.org/mailman/listinfo/python-list
Re: Return value of an assignment statement?
On 21 fév, 23:06, Jeff Schwab [EMAIL PROTECTED] wrote: John Henry wrote: On Feb 21, 1:48 pm, John Henry [EMAIL PROTECTED] wrote: On Feb 21, 1:43 pm, mrstephengross [EMAIL PROTECTED] wrote: Hi all. In C, an assignment statement returns the value assigned. For instance: int x int y = (x = 3) In the above example, (x=3) returns 3, which is assigned to y. In python, as far as I can tell, assignment statements don't return anything: y = (x = 3) The above example generates a SyntaxError. Is this correct? I just want to make sure I've understood the semantics. Thanks, --Steve That's true, and I am happy that they decided to make that a syntax error. BTW: The less obvious issues when coming from the C world are Python syntax like these: y = x = 3 a = 4 y = x = a print x,y a = 5 print x,y That's the same behavior I would expect in C, on the grounds that C assignments do bit-wise copies. What I found confusing at first was that the same variable will either directly store or merely refer to an object, depending on the type of the object: a = [ 'hello' ] y = x = a a += [ 'world' ] print x, y ['hello', 'world'] ['hello', 'world'] There's nothing like a variable storing anything in Python. All you have are names to (references to) objects binding in a namespace. Now the fact is that some types are mutable and other are not. In your above example, the augmented assignment does *not* rebind a, but invoke a.extend(). With integers, it would have rebind a. So while your observation is exact, your interpretation is wrong !-) -- http://mail.python.org/mailman/listinfo/python-list
Re: Return value of an assignment statement?
[EMAIL PROTECTED] wrote: On 21 fév, 23:19, John Henry [EMAIL PROTECTED] wrote: On Feb 21, 2:06 pm, Jeff Schwab [EMAIL PROTECTED] wrote: John Henry wrote: On Feb 21, 1:48 pm, John Henry [EMAIL PROTECTED] wrote: On Feb 21, 1:43 pm, mrstephengross [EMAIL PROTECTED] wrote: Hi all. In C, an assignment statement returns the value assigned. For instance: int x int y = (x = 3) In the above example, (x=3) returns 3, which is assigned to y. In python, as far as I can tell, assignment statements don't return anything: y = (x = 3) The above example generates a SyntaxError. Is this correct? I just want to make sure I've understood the semantics. Thanks, --Steve That's true, and I am happy that they decided to make that a syntax error. BTW: The less obvious issues when coming from the C world are Python syntax like these: y = x = 3 a = 4 y = x = a print x,y a = 5 print x,y That's the same behavior I would expect in C, on the grounds that C assignments do bit-wise copies. What I found confusing at first was that the same variable will either directly store or merely refer to an object, depending on the type of the object: a = [ 'hello' ] y = x = a a += [ 'world' ] print x, y ['hello', 'world'] ['hello', 'world'] Yep. Took me a while to realize there is mutable objects, and non- mutable objects. To be honest, I am still not too comfortable about it. For instance, I still get nervous for code like: def invoke_some_fct(parent): y = parent.x y += [ 'world' ] print y, parent.x class abc: def __init__(self): self.x=[ 'hello' ] invoke_some_fct(self) print self.x Explicitely using list.extend would make things clearer: def invoke_some_fct(parent): parent.x.extend(['world']) Whether you use += or extend has nothing to do with it. You omitted the relevant part. Using extend, it would look like: y = parent.x y.extend(['world']) The confusing part is that performing an operation on y may or may not alter parent.x, depending on whether the initial type of parent.x is immutable. If parent.x is immutable, y is a copy of the value represented by parent.x, and modifying y has not effect on the value of parent.x. If (OTOH) parent.x is mutable, then x and y are really references to the same object, and modifications to that object via y can be observed via x. In C, you use pointers to get this effect. Now there's no reason to feel nervous about this. All you have to remember is that Python never copy anything unless explicitely asked for. It's not that simple. After a statement like: a = b Whether a and b denote the same object depends on what kind of object b represented in the first place. -- http://mail.python.org/mailman/listinfo/python-list
Re: Return value of an assignment statement?
Jeff Schwab wrote: [EMAIL PROTECTED] wrote: [...] Now there's no reason to feel nervous about this. All you have to remember is that Python never copy anything unless explicitely asked for. It's not that simple. After a statement like: a = b Whether a and b denote the same object depends on what kind of object b represented in the first place. Surely this is exactly wrong. Is there a single example you can think of where a = b assert a is b, Oops! would raise and exception? Perhaps you meant to use an augmented assignment operation? regards Steve -- Steve Holden+1 571 484 6266 +1 800 494 3119 Holden Web LLC http://www.holdenweb.com/ -- http://mail.python.org/mailman/listinfo/python-list
Re: Return value of an assignment statement?
mrstephengross wrote: What you can't do (that I really miss) is have a tree of assign-and-test expressions: import re pat = re.compile('some pattern') if m = pat.match(some_string): do_something(m) Yep, this is exactly what I am (was) trying to do. Oh well Any clever ideas on this front? The syntax is the way it is precisely to discourage that kind of clever idea. Of course, people nevertheless manage to work around the restriction to try and make their Python read like some other language they are more familiar with, and most of the time they get away with it. The fat remains that in programming there *is* such a thing as being too clever, and Python's syntax deliberately discourages that. regards Steve -- Steve Holden+1 571 484 6266 +1 800 494 3119 Holden Web LLC http://www.holdenweb.com/ -- http://mail.python.org/mailman/listinfo/python-list
Re: Return value of an assignment statement?
Terry Reedy wrote: Jeff Schwab [EMAIL PROTECTED] wrote in message news:[EMAIL PROTECTED] | That's the same behavior I would expect in C, on the grounds that C | What I found confusing at first was | that the same variable will either directly store or merely refer to an | object, depending on the type of the object: Since names and collection slots always refer to objects, I find the above confusing. Can you clarify what difference you percieve? a += b Whether a refers to the same object before and after that statement depends on what type of object it referred to before the statement. -- http://mail.python.org/mailman/listinfo/python-list
Re: Return value of an assignment statement?
[EMAIL PROTECTED] wrote: On 21 fév, 23:06, Jeff Schwab [EMAIL PROTECTED] wrote: John Henry wrote: On Feb 21, 1:48 pm, John Henry [EMAIL PROTECTED] wrote: On Feb 21, 1:43 pm, mrstephengross [EMAIL PROTECTED] wrote: Hi all. In C, an assignment statement returns the value assigned. For instance: int x int y = (x = 3) In the above example, (x=3) returns 3, which is assigned to y. In python, as far as I can tell, assignment statements don't return anything: y = (x = 3) The above example generates a SyntaxError. Is this correct? I just want to make sure I've understood the semantics. Thanks, --Steve That's true, and I am happy that they decided to make that a syntax error. BTW: The less obvious issues when coming from the C world are Python syntax like these: y = x = 3 a = 4 y = x = a print x,y a = 5 print x,y That's the same behavior I would expect in C, on the grounds that C assignments do bit-wise copies. What I found confusing at first was that the same variable will either directly store or merely refer to an object, depending on the type of the object: a = [ 'hello' ] y = x = a a += [ 'world' ] print x, y ['hello', 'world'] ['hello', 'world'] There's nothing like a variable storing anything in Python. All you have are names to (references to) objects binding in a namespace. Now the fact is that some types are mutable and other are not. In your above example, the augmented assignment does *not* rebind a, but invoke a.extend(). With integers, it would have rebind a. So while your observation is exact, your interpretation is wrong !-) Thank you for the clarification. For some reason, I had it in my head that ints were packed directly into the C structures that represent Python variables, in the same (union?) member that otherwise would store a pointer. -- http://mail.python.org/mailman/listinfo/python-list
Re: Return value of an assignment statement?
Steve Holden wrote: Jeff Schwab wrote: [EMAIL PROTECTED] wrote: [...] Now there's no reason to feel nervous about this. All you have to remember is that Python never copy anything unless explicitely asked for. It's not that simple. After a statement like: a = b Whether a and b denote the same object depends on what kind of object b represented in the first place. Surely this is exactly wrong. Is there a single example you can think of where a = b a += b (my bad) assert a is b, Oops! would raise and exception? Perhaps you meant to use an augmented assignment operation? Why, yes I did! Sorry about that. -- http://mail.python.org/mailman/listinfo/python-list
Re: Return value of an assignment statement?
Steve Holden wrote: mrstephengross wrote: What you can't do (that I really miss) is have a tree of assign-and-test expressions: import re pat = re.compile('some pattern') if m = pat.match(some_string): do_something(m) Yep, this is exactly what I am (was) trying to do. Oh well Any clever ideas on this front? The syntax is the way it is precisely to discourage that kind of clever idea. Of course, people nevertheless manage to work around the restriction to try and make their Python read like some other language they are more familiar with, and most of the time they get away with it. The fat remains that in programming there *is* such a thing as being too clever, and Python's syntax deliberately discourages that. This isn't clever. It's what most of us were taught, from the beginning, was best practice. In some languages (including C and C++) the above is extremely common and perfectly acceptable. -- http://mail.python.org/mailman/listinfo/python-list
Re: Return value of an assignment statement?
On Feb 21, 7:21 pm, Jeff Schwab [EMAIL PROTECTED] wrote: Steve Holden wrote: Jeff Schwab wrote: [EMAIL PROTECTED] wrote: [...] Now there's no reason to feel nervous about this. All you have to remember is that Python never copy anything unless explicitely asked for. It's not that simple. After a statement like: a = b Whether a and b denote the same object depends on what kind of object b represented in the first place. Surely this is exactly wrong. Is there a single example you can think of where a = b a += b (my bad) assert a is b, Oops! would raise and exception? Perhaps you meant to use an augmented assignment operation? Why, yes I did! Sorry about that. It seems less surprising when you keep in mind that += (and friends) can be syntax sugar for calling a method on the right hand side object: a += b = a.__iadd__(b). It's up to the class of 'a' to do whatever within this method (whether it's a good idea to do anything else other than modify 'self' in place is another thing). Would you be able to say anything about a.foo(b) without knowing what 'a' is ? The only difference is that for types that don't implement an augmented operator, a `op`= b translates to a = a `op` b for a binary operator `op`. There's no formal notion of mutable and immutable objects with respect to these operators; any class that doesn't implement them is immutable as far as augmented assignment goes (of course it may be mutated in other ways, e.g. by fiddling with a.__dict__ directly). On the other hand, a = b does always the same thing; unlike C++, '=' is not an operator and therefore it cannot be overriden by the class of 'a'. George -- http://mail.python.org/mailman/listinfo/python-list
Re: Return value of an assignment statement?
In article [EMAIL PROTECTED], Jeff Schwab [EMAIL PROTECTED] wrote: [EMAIL PROTECTED] wrote: There's nothing like a variable storing anything in Python. All you have are names to (references to) objects binding in a namespace. Now the fact is that some types are mutable and other are not. In your above example, the augmented assignment does *not* rebind a, but invoke a.extend(). With integers, it would have rebind a. So while your observation is exact, your interpretation is wrong !-) Thank you for the clarification. For some reason, I had it in my head that ints were packed directly into the C structures that represent Python variables, in the same (union?) member that otherwise would store a pointer. Notice very very carefully that Bruno is not using variable. Many expert Python programmers strongly prefer to talk about names instead of variables (especially when explaining the Python object model) precisely because using variable leads to incorrect expectations. http://starship.python.net/crew/mwh/hacks/objectthink.html -- Aahz ([EMAIL PROTECTED]) * http://www.pythoncraft.com/ All problems in computer science can be solved by another level of indirection. --Butler Lampson -- http://mail.python.org/mailman/listinfo/python-list
Re: Return value of an assignment statement?
George Sakkis wrote: On Feb 21, 7:21 pm, Jeff Schwab [EMAIL PROTECTED] wrote: Steve Holden wrote: Jeff Schwab wrote: [EMAIL PROTECTED] wrote: [...] Now there's no reason to feel nervous about this. All you have to remember is that Python never copy anything unless explicitely asked for. It's not that simple. After a statement like: a = b Whether a and b denote the same object depends on what kind of object b represented in the first place. Surely this is exactly wrong. Is there a single example you can think of where a = b a += b (my bad) assert a is b, Oops! would raise and exception? Perhaps you meant to use an augmented assignment operation? Why, yes I did! Sorry about that. It seems less surprising when you keep in mind that += (and friends) can be syntax sugar for calling a method on the right hand side object: a += b = a.__iadd__(b). It's up to the class of 'a' to do whatever within this method (whether it's a good idea to do anything else other than modify 'self' in place is another thing). Would you be able to say anything about a.foo(b) without knowing what 'a' is ? Yes: I would know that it didn't rebind a. The only difference is that for types that don't implement an augmented operator, a `op`= b translates to a = a `op` b for a binary operator `op`. There's no formal notion of mutable and immutable objects with respect to these operators; any class that doesn't implement them is immutable as far as augmented assignment goes (of course it may be mutated in other ways, e.g. by fiddling with a.__dict__ directly). Thanks for explaining that. On the other hand, a = b does always the same thing; unlike C++, '=' is not an operator and therefore it cannot be overriden by the class of 'a'. Not an operator? Then what is it? -- http://mail.python.org/mailman/listinfo/python-list
Re: Return value of an assignment statement?
Aahz wrote: In article [EMAIL PROTECTED], Jeff Schwab [EMAIL PROTECTED] wrote: [EMAIL PROTECTED] wrote: There's nothing like a variable storing anything in Python. All you have are names to (references to) objects binding in a namespace. Now the fact is that some types are mutable and other are not. In your above example, the augmented assignment does *not* rebind a, but invoke a.extend(). With integers, it would have rebind a. So while your observation is exact, your interpretation is wrong !-) Thank you for the clarification. For some reason, I had it in my head that ints were packed directly into the C structures that represent Python variables, in the same (union?) member that otherwise would store a pointer. Notice very very carefully that Bruno is not using variable. Many expert Python programmers strongly prefer to talk about names instead of variables (especially when explaining the Python object model) precisely because using variable leads to incorrect expectations. http://starship.python.net/crew/mwh/hacks/objectthink.html So what is the variable? Or is Python the first HLL I've ever heard of that didn't have variables? -- http://mail.python.org/mailman/listinfo/python-list
Re: Return value of an assignment statement?
Jeff Schwab [EMAIL PROTECTED] writes: So what is the variable? Or is Python the first HLL I've ever heard of that didn't have variables? I don't know what other HLL's you use, but some languages don't even have mutable values. -- http://mail.python.org/mailman/listinfo/python-list
Re: Return value of an assignment statement?
Hallöchen! Jeff Schwab writes: Aahz wrote: [...] Notice very very carefully that Bruno is not using variable. Many expert Python programmers strongly prefer to talk about names instead of variables (especially when explaining the Python object model) precisely because using variable leads to incorrect expectations. http://starship.python.net/crew/mwh/hacks/objectthink.html So what is the variable? Or is Python the first HLL I've ever heard of that didn't have variables? Since Python objects, names, their operations, and the syntax used for it resemble very closely (but not completely) what is called variable in other languages, Python names are mostly called variables, too. But there is this one thing of changing mutable objects which may also change the value of other variables. This can only be understood if your nomenclature is strictly correct. I find Python's model is this area great. It makes many things simpler and only one or two things more complicated. I had my bad experiences with it, too (e.g. initialising two lists with x_values=y_values=[]). But only once per year I stumble over it. Tschö, Torsten. -- Torsten Bronger, aquisgrana, europa vetus Jabber ID: [EMAIL PROTECTED] (See http://ime.webhop.org for further contact info.) -- http://mail.python.org/mailman/listinfo/python-list
Re: Return value of an assignment statement?
On Feb 22, 12:26 am, Jeff Schwab [EMAIL PROTECTED] wrote: On the other hand, a = b does always the same thing; unlike C++, '=' is not an operator and therefore it cannot be overriden by the class of 'a'. Not an operator? Then what is it? In this context, it's just the token used for the assignment statement. In short, if 'a' is an identifier, the statement means bind the name 'a' to the object 'b' (in the local or global namespace). It doesn't say anything about memory allocation, initialization or copying. The only case where assigning an identifier affects memory is the following [1]: The name is rebound if it was already bound. This may cause the reference count for the object previously bound to the name to reach zero, causing the object to be deallocated and its destructor (if it has one) to be called. HTH, George [1] http://docs.python.org/ref/assignment.html -- http://mail.python.org/mailman/listinfo/python-list
Re: Return value of an assignment statement?
Jeff Schwab [EMAIL PROTECTED] writes: Aahz wrote: Notice very very carefully that Bruno is not using variable. Many expert Python programmers strongly prefer to talk about names instead of variables (especially when explaining the Python object model) precisely because using variable leads to incorrect expectations. http://starship.python.net/crew/mwh/hacks/objectthink.html So what is the variable? Or is Python the first HLL I've ever heard of that didn't have variables? I don't know what HLLs you've heard of. I would bet that some of them are languages which don't have variables *with all that the term implies to most programmers*. You don't have to go very far to find Python programmers using the term variable. What Aahz is pointing out is that the concepts that people sloppily refer to by the term variable don't behave in Python the way a programmer might expect who has used that term in reference to concepts native to other languages. Hence the term requires careful definition, and it's often best simply not to use it and use the better analogy of names and binding instead. -- \ Pinky, are you pondering what I'm pondering? I think so, | `\Brain, but if the plural of mouse is mice, wouldn't the plural | _o__) of spouse be spice? -- _Pinky and The Brain_ | Ben Finney -- http://mail.python.org/mailman/listinfo/python-list