Re: Return value of an assignment statement?

2008-02-27 Thread Bruno Desthuilliers
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?

2008-02-27 Thread Bruno Desthuilliers
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?

2008-02-27 Thread Bruno Desthuilliers
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?

2008-02-26 Thread Aahz
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?

2008-02-24 Thread Marc 'BlackJack' Rintsch
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?

2008-02-23 Thread Marc 'BlackJack' Rintsch
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?

2008-02-23 Thread Bob Martin
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?

2008-02-23 Thread Paul Rudin
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?

2008-02-23 Thread Steve Holden
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?

2008-02-23 Thread Jeff Schwab
[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?

2008-02-23 Thread Jeff Schwab
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?

2008-02-23 Thread Paddy
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?

2008-02-23 Thread Arnaud Delobelle
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?

2008-02-23 Thread Jeff Schwab
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?

2008-02-23 Thread John Henry
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?

2008-02-23 Thread Tim Roberts
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?

2008-02-23 Thread Terry Reedy

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?

2008-02-22 Thread Marc 'BlackJack' Rintsch
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?

2008-02-22 Thread Carl Banks
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?

2008-02-22 Thread Carl Banks
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?

2008-02-22 Thread Duncan Booth
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?

2008-02-22 Thread Paul Rubin
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?

2008-02-22 Thread Duncan Booth
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?

2008-02-22 Thread Bruno Desthuilliers
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?

2008-02-22 Thread Steven D'Aprano
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?

2008-02-22 Thread Steven D'Aprano
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?

2008-02-22 Thread Steven D'Aprano
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?

2008-02-22 Thread Marc 'BlackJack' Rintsch
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?

2008-02-22 Thread Carl Banks
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?

2008-02-22 Thread Steve Holden
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?

2008-02-22 Thread Steve Holden
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?

2008-02-22 Thread Steven D'Aprano
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?

2008-02-22 Thread Aahz
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?

2008-02-22 Thread Aahz
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?

2008-02-22 Thread Jeff Schwab
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?

2008-02-22 Thread Steven D'Aprano
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?

2008-02-22 Thread Paul Rubin
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?

2008-02-22 Thread George Sakkis
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?

2008-02-21 Thread mrstephengross
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?

2008-02-21 Thread John Henry
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?

2008-02-21 Thread Jeff Schwab
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?

2008-02-21 Thread 7stud
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?

2008-02-21 Thread John Henry
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?

2008-02-21 Thread mrstephengross
 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?

2008-02-21 Thread Jeff Schwab
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?

2008-02-21 Thread Jeff Schwab
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?

2008-02-21 Thread John Henry
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?

2008-02-21 Thread Martin v. Löwis
 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?

2008-02-21 Thread Terry Reedy

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?

2008-02-21 Thread [EMAIL PROTECTED]
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?

2008-02-21 Thread [EMAIL PROTECTED]
 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?

2008-02-21 Thread [EMAIL PROTECTED]
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?

2008-02-21 Thread Jeff Schwab
[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?

2008-02-21 Thread Steve Holden
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?

2008-02-21 Thread Steve Holden
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?

2008-02-21 Thread Jeff Schwab
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?

2008-02-21 Thread Jeff Schwab
[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?

2008-02-21 Thread Jeff Schwab
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?

2008-02-21 Thread Jeff Schwab
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?

2008-02-21 Thread George Sakkis
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?

2008-02-21 Thread Aahz
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?

2008-02-21 Thread Jeff Schwab
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?

2008-02-21 Thread Jeff Schwab
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?

2008-02-21 Thread Paul Rubin
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?

2008-02-21 Thread Torsten Bronger
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?

2008-02-21 Thread George Sakkis
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?

2008-02-21 Thread Ben Finney
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