Re: Use cases for del

2005-07-10 Thread Reinhold Birkenfeld
Ron Adam wrote:

  'abc' is 'abcd'[:3]
 False
 
 Well of course it will be false... your testing two different strings! 
 And the resulting slice creates a third.

 Try:
 
 ABC = 'abc'
 
 value = ABC
 if value is ABC:   # Test if it is the same object
 pass

That's not going to buy you any time above the is None, because identity-
testing has nothing to do with the type of the object.

Additionally, using is with immutable objects is horrible.

Reinhold
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Use cases for del

2005-07-10 Thread Ron Adam
Reinhold Birkenfeld wrote:
 Ron Adam wrote:
 
 
 'abc' is 'abcd'[:3]
False

Well of course it will be false... your testing two different strings! 
And the resulting slice creates a third.

Try:

ABC = 'abc'

value = ABC
if value is ABC:   # Test if it is the same object
pass
 
 
 That's not going to buy you any time above the is None, because identity-
 testing has nothing to do with the type of the object.

Ok, I retested it... Not sure why I was coming up with a small 
difference before.  shrug  It seemed strange to me at the time which 
is part of why I asked.

My point was using strings could work in same context as None,  (if 
None acted as del), with out a performance penalty.  Anyway, this is all 
moot as it's an solution to a hypothetical situation that is not a good 
idea.

 Additionally, using is with immutable objects is horrible.

Why is it horrible?  Oh nevermind.  ;-)


Cheers,
Ron


 Reinhold
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Use cases for del

2005-07-10 Thread Terry Reedy

Ron Adam [EMAIL PROTECTED] wrote in message 
news:[EMAIL PROTECTED]
 To avoid that you either need to define the flag string as a global name
 or use it strictly in the local scope it's defined in.  Python will also
 sometimes reuse strings as an optimization instead of creating a second
 string if they are equal.  Something else to be aware of.

I believe CPython's string equality function first checks the two strings 
for identity.  So one gets most of the benefit of 'is' testing anyway.  (An 
I presume it next check for length equality.)

tjr 



-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Use cases for del

2005-07-09 Thread Scott David Daniels
Ron Adam wrote:
 George Sakkis wrote:
 
 I get:

 None: 0.54952316
 String: 0.498000144958
 is None: 0.45047684
 
 
 What do yo get for name is 'string' expressions?

  'abc' is 'abcd'[:3]
 False

You need to test for equality (==), not identity (is) when
equal things may be distinct.  This is true for floats, strings,
and most things which are not identity-based (None, basic classes).
This is also true for longs and most ints (an optimization that makes
small ints use a single identity can lead you to a mistaken belief
that equal integers are always identical.

  (12345 + 45678) is (12345 + 45678)
 False

'is' tests for identity match.  a is b is roughly equivalent to
id(a) == id(b).  In fact an optimization inside string comparisons
is the C equivalent of return (id(a) == id(b) of len(a) == len(b)
and elements match)

--Scott David Daniels
[EMAIL PROTECTED]
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Use cases for del

2005-07-08 Thread Ron Adam
Steven D'Aprano wrote:

 Ron Adam wrote:

 def count_records(record_obj, start=0, end=len(record_obj)):
 
 
 That would work really well, except that it doesn't work at all.

Yep, and I have to stop trying to post on too little sleep.


Ok, how about... ?


def count_records(record_obj, start=0, end='to-end'):
 if end == 'to-end':
 end = len(record_obj)
 n = 0
 for rec in record_obj.data[start:end]:
 if not rec.isblank():
 n += 1
 return n


This isn't really different from using None. While it's possible to 
avoid None, its probably not worth the trouble.  I use it myself.


Here's something interesting:

import time

x = None
t = time.time()
for i in range(100):
 if x==None:
 pass
print 'None:',time.time()-t

x = 'to-end'
t = time.time()
for i in range(100):
 if x=='to-end':
 pass
print 'String:',time.time()-t

 
None: 0.4673515
String: 0.36133514


Of course the difference this would make on a single call in practically 
Nill.

Anyway, time to call it a night so tomorrow I don't make anymore silly 
mistakes on comp.lang.python. :)

Cheers,
Ron

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Use cases for del

2005-07-08 Thread George Sakkis
Ron Adam [EMAIL PROTECTED] wrote:

 Here's something interesting:

 import time

 x = None
 t = time.time()
 for i in range(100):
  if x==None:
  pass
 print 'None:',time.time()-t

 x = 'to-end'
 t = time.time()
 for i in range(100):
  if x=='to-end':
  pass
 print 'String:',time.time()-t

  
 None: 0.4673515
 String: 0.36133514


 Of course the difference this would make on a single call in practically
 Nill.


How about using the right way of comparing with None ?

x = None
t = time.time()
for i in range(100):
  if x is None:
  pass
print 'is None:',time.time()-t

I get:

None: 0.54952316
String: 0.498000144958
is None: 0.45047684

 Anyway, time to call it a night so tomorrow I don't make anymore silly
 mistakes on comp.lang.python. :)

That would be a great idea ;-) An even greater idea would be to give up
on this None should mean undefined babble; it looks like a solution
looking for a problem and it raises more complications than it actually
solves (assuming it does actually solve anything, which is not quite
obvious).

 Cheers,
 Ron

Cheers,
George

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Use cases for del

2005-07-08 Thread Scott David Daniels
Ron Adam wrote:
 Here's something interesting:
 
 import time
 
 x = None
 t = time.time()
 for i in range(100):
 if x==None:
 pass
 print 'None:',time.time()-t
 
 x = 'to-end'
 t = time.time()
 for i in range(100):
 if x=='to-end':
 pass
 print 'String:',time.time()-t
 
  
 None: 0.4673515
 String: 0.36133514
 
 
 Of course the difference this would make on a single call in practically 
 Nill.
 
 Anyway, time to call it a night so tomorrow I don't make anymore silly 
 mistakes on comp.lang.python. :)
 
 Cheers,
 Ron
 

Try this:
import time
def timed(number):
 nreps = ereps = [None] * number
 t0 = time.time()
 x = None
 for i in ereps:
 if x == None:
 pass
 x = 'to-' + 'end' # make sure equal string, not identical string
 for i in nreps:
 if x == None:
 pass
 t1 = time.time()
 for i in ereps:
 if x == 'to-end':
 pass
 x = None
 for i in nreps:
 if x == 'to-end':
 pass
 t2 = time.time()
 x = None
 for i in ereps:
 if x is None:
 pass
 x = 'to-end'  # magic unnecessary here.
 for i in nreps:
 if x is None: pass
 return t0, t1, t2, time.time()

t0, t1, t2, t3 = timed(100)
print '== None:', t1 - t0
print '== String:', t2 - t1
print 'is None:', t3 - t2
===
== None: 0.57868665
== String: 0.594000101089
is None: 0.3123624

Testing for None should be an is-test (not just for speed). In
older pythons the == result wasn't necessarily same as is-test.
This made sense to me after figuring out NULL in database stuff.
is-test will always work for None despite the other half.  Not
so for bogus objects like:

  class WildCard(object):
 def __eq__(self, other):
 return True

  (WildCard() is None), (None is WildCard())
(False, False)
  (WildCard() == None), (None == WildCard())
(True, True)

--Scott David Daniels
[EMAIL PROTECTED]
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Use cases for del

2005-07-08 Thread Daniel Dittmar
Scott David Daniels wrote:
 Testing for None should be an is-test (not just for speed). In
 older pythons the == result wasn't necessarily same as is-test.
 This made sense to me after figuring out NULL in database stuff.

NULL in SQL databases has nothing to do with Python None. I'm quite sure 
that None == None always returned boolean true.

In a SQL database, NULL = NULL will always return NULL, which is prety 
much the same as FALSE. Except for NOT, AS NOT NULL is NULL.

Daniel
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Use cases for del

2005-07-08 Thread Roy Smith
Daniel Dittmar  [EMAIL PROTECTED] wrote:
 In a SQL database, NULL = NULL will always return NULL, which is prety 
 much the same as FALSE. Except for NOT, AS NOT NULL is NULL.

SQL's NULL is very much akin to the IEEE NaN (not quite, but close).
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Use cases for del

2005-07-07 Thread Steven D'Aprano
Ron Adam wrote:

 Why would you want to use None as an integer value?
 
 If a value isn't established yet, then do you need the name defined? 
 Wouldn't it be better to wait until you need the name then give it a value?

Er, maybe I'm misunderstanding something here, but 
surely the most obvious case is for default and special 
function arguments:

def count_records(record_obj, start=0, end=None):
 if end == None:
 end = len(record_obj)
 if start == None:  # this is not the default!
 # start at the current position
 start = record_obj.current
 n = 0
 for rec in record_obj.data[start:end]:
 if not rec.isblank():
 n += 1
 return n

which you call with:

# current position to end
count_records(myRecords, None)
# start to end
count_records(myRecords)
# start to current position
count_records(myRecords, end=myRecords.current)

-- 
Steven.

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Use cases for del

2005-07-07 Thread Grant Edwards
On 2005-07-07, Ron Adam [EMAIL PROTECTED] wrote:

class demo:
   def foo(v=None):
   if v is not None:
   self.v = v
   return self.v   

 You are really checking if v exists, so having it undefined in
 namespace as the default is consistent with what you are
 doing.

 As I said above...

 It would be a way to set an argument as being optional without
 actually assigning a value to it.

 So it would still work like you expect even though v is not
 bound to anything.  Like I said the bigger problem is that
 globals will be visible and that would create a conflict.
 Setting a value to None in a function hides globals of the
 same name.  That wouldn't happen if None unbound names as del
 does.

Good point.  I hadn't thought of that.

 So you would need to use something else for that purpose I
 suppose, but that was why None became a literal in the first
 place, so maybe it's taking a step backwards.


 2) So I can use it as sort of a NaN equivalent.
 
if self.fd is None:
   self.fd = os.open('foo.bar','w')

if self.fd is not None:
   os.close(self.fd)
   self.fd = None  

 It would still work as you expect.  A while back I suggested an 'also' 
 for if that would do exactly that with only one test.  Nobody liked it.

   if self.fd is None:
  self.fd = os.open('foo.bar','w')
  # do something with self.fd

   also:
  os.close(self.fd)
  self.fd = None


If a value isn't established yet, then do you need the name
defined?
  
 I find it more obvious to set the name to None during the
 periods that it isn't valid than to delete it and check for a
 NameError when I want to know if the value is usable or not.

 You would still be able to do that explicitly and it probably would be a 
 good idea when you aren't sure if a name is left over from something else.

 If a name is None, it means it's available and unassigned, so
 you don't have to check for a NameError.

How would you spell if a name is None?

Personally, I think the spellings

   del name
   if 'name' in locals()

is much more explicit/obvious than

   name = None
   name is None   

I expect the = operator to bind a name to a value.  Having it
do something completely different some of the time seems a bit
unpythonic.
   
-- 
Grant Edwards   grante Yow!  Today, THREE WINOS
  at   from DETROIT sold me a
   visi.comframed photo of TAB HUNTER
   before his MAKEOVER!
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Use cases for del

2005-07-07 Thread Ron Adam
Grant Edwards wrote:

 On 2005-07-07, Ron Adam [EMAIL PROTECTED] wrote:

It would be a way to set an argument as being optional without
actually assigning a value to it.

So it would still work like you expect even though v is not
bound to anything.  Like I said the bigger problem is that
globals will be visible and that would create a conflict.
Setting a value to None in a function hides globals of the
same name.  That wouldn't happen if None unbound names as del
does.
 
 Good point.  I hadn't thought of that.

The easiest way to fix that is to create a Nil or Null object as a 
replacement for the current None object.


I find it more obvious to set the name to None during the
periods that it isn't valid than to delete it and check for a
NameError when I want to know if the value is usable or not.

You would still be able to do that explicitly and it probably would be a 
good idea when you aren't sure if a name is left over from something else.

If a name is None, it means it's available and unassigned, so
you don't have to check for a NameError.
 
 
 How would you spell if a name is None?

How about:

if name is None: name = something

Making None the same as undefined wouldn't change this.  I think the 
parser would need to be a little smarter where None is concerned in 
order to be able to handle it in bool expressions,  and catch improper 
name = undefined assignments.

But it might not change things as much as you think.


 Personally, I think the spellings
 
del name
if 'name' in locals()
 
 is much more explicit/obvious than
 
name = None
name is None   

This would be
  name = None # remove it from locals()
  if name is None: dosomething# if it's not in locals()

No need to check locals or globals.  That's one of the plus's I think.


Since we can already assign a value to any name without first 
initializing it,  this just allows us to use it in a some expressions 
without also first initializing it.  It would still give an error if we 
tried to use it in any operation.  Just like the present None.


 I expect the = operator to bind a name to a value.  Having it
 do something completely different some of the time seems a bit
 unpythonic.

But you are assigning it a value. Instead of having a Name assigned to a 
None object, the name is just removed from name space to do the same 
thing and you save some memory in the process.



How about keeping None as it is as a place holder object, and having a 
keyword called undefined instead.

x = 3
x = undefined   # delete x from name space
if x is not undefined: print x

if an undefined name is used with any operator, it could give a 
'UndefinedName' error.

This would be more compatible with the current python language.

Cheers,
Ron

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Use cases for del

2005-07-07 Thread Ron Adam
Steven D'Aprano wrote:

 Ron Adam wrote:
 
 Why would you want to use None as an integer value?

 If a value isn't established yet, then do you need the name defined? 
 Wouldn't it be better to wait until you need the name then give it a 
 value?
 
 
 Er, maybe I'm misunderstanding something here, but surely the most 
 obvious case is for default and special function arguments:
 
 def count_records(record_obj, start=0, end=None):
 if end == None:
 end = len(record_obj)
 if start == None:  # this is not the default!
 # start at the current position
 start = record_obj.current
 n = 0
 for rec in record_obj.data[start:end]:
 if not rec.isblank():
 n += 1
 return n
 
 which you call with:
 
 # current position to end
 count_records(myRecords, None)
 # start to end
 count_records(myRecords)
 # start to current position
 count_records(myRecords, end=myRecords.current)


You have three possible outcomes,
count all
count range
count using current index
count range from beginning to current
count range from current to end


The most consistent way to do this would be:


def count_records(record_obj, start=0, end=len(record_obj)):
 n = 0
 for rec in record_obj.data[start:end]:
 if not rec.isblank():
 n += 1
 return n


# current position to end
count_records(myRecords, myRecords.current)

# start to end
count_records(myRecords)

# start to current position
count_records(myRecords, end=myRecords.current)


Cheers,
Ron



-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Use cases for del

2005-07-07 Thread Dieter Maurer
Daniel Dittmar [EMAIL PROTECTED] writes on Wed, 06 Jul 2005 16:12:46 +0200:
 Peter Hansen wrote:
  Arguing the case for del: how would I, in doing automated testing,
  ensure that I've returned everything to a clean starting point in
  all cases if I can't delete variables?  Sometimes a global is the
  simplest way to do something... how do I delete a global if not with
  del?
 
 
 globals ().__delitem__ (varname)
 
 except that the method would probably be called delete.

You now have a uniform way to remove an object from a namespace.

Why would you want to give each namespace its own method to
remove objects from it?

Can you imagine how much code you would break (would your proposal
to remove del got accepted)?


Dieter
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Use cases for del

2005-07-07 Thread Peter Hansen
Duncan Booth wrote:
 Peter Hansen wrote:
Tom Anderson wrote:
How about just getting rid of del? 

Arguing the case for del: how would I, in doing automated testing, 
ensure that I've returned everything to a clean starting point in all 
cases if I can't delete variables?  Sometimes a global is the simplest 
way to do something... how do I delete a global if not with del.
 
 I generally find that unit tests force me to structure the code in a 
 cleaner manner, e.g. to not use globals as much, but if you do need to 
 delete a global you do it in exactly the same way as you delete anything: 
 use the del statement:

Umm: huh?  Tom suggested getting rid of del, I suggested it was required 
for some cases in doing testing in the fact of globals (for cases where 
they are the simplest approach), then you suggest that the correct 
approach is to use del.

Well, I agree (including your point on use of globals, which I attempted 
to anticipate with my comment starting sometimes), but I don't really 
see the point of your posting, Duncan...  it appears redundant on all 
counts.

-Peter
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Use cases for del

2005-07-07 Thread George Sakkis
Grant Edwards [EMAIL PROTECTED] wrote:

 On 2005-07-07, George Sakkis [EMAIL PROTECTED] wrote:

  I guess he means why not define foo as property:
 
  class demo(object):
  foo = property(fget = lambda self: self.v,
 fset = lambda self,v: setattr(self,'v',v))
 
  d = demo()
  d.foo = 3
  print d.foo

 In some ways that's even cleaner.

 In my simplivied example all the foo() method was doing was
 setting/returning an attribute, but usually there's a bit more
 going on (e.g. system calls with possible side effects).

 To me it's a bit more explicit that

   d.foo(3)
   d.foo()

 are doing something other than just getting/setting the value
 of an instance attribute.  If all I really wanted to do was
 get/set the instance's v attribute, I probably would have
 just done it like this

   d.v = 3
   print d.v

The main reason for bringing properties into the language was exactly
to *hide* the fact that something else might be going one behind the
scenes. Ideally, the user of the class shouldn't care [1] whether
getting an attribute returns a stored value in the instance's __dict__,
computes it on the fly, fetches it from a cache or a database, etc, and
similarly for setting the attribute.

George

[1] OTOH the user should probably be aware if a specific property (or
any callable for that matter) implies significant performance (or
other) costs.

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Use cases for del

2005-07-07 Thread Steven D'Aprano
Ron Adam wrote:

 Steven D'Aprano wrote:
 Er, maybe I'm misunderstanding something here, but surely the most 
 obvious case is for default and special function arguments:

 def count_records(record_obj, start=0, end=None):
 if end == None:
 end = len(record_obj)
 if start == None:  # this is not the default!
 # start at the current position
 start = record_obj.current
 n = 0
 for rec in record_obj.data[start:end]:
 if not rec.isblank():
 n += 1
 return n

[snip]

 You have three possible outcomes,
count all
count range
count using current index
count range from beginning to current
count range from current to end

That makes four outcomes by my count.

 The most consistent way to do this would be:
 
 def count_records(record_obj, start=0, end=len(record_obj)):

That would work really well, except that it doesn't 
work at all.

At the time the function is defined, record_obj doesn't 
exist, so there is no way of telling what it's length 
will be when the function is called. Here is a simpler 
example showing the problem:

py def func(s, start=0, end=len(s)):
... return s[start:end]
...
Traceback (most recent call last):
   File stdin, line 1, in ?
NameError: name 's' is not defined

The only way this strategy works is if there is a 
global variable s which defines a __len__ method. But 
then the default value of end will be fixed to the 
length of that global for all time (or at least until 
the module is reloaded).

So given a pre-existing global variable, you get a 
class of hard-to-debug bugs:

py s = [0, 1, 2, 3]
py def func(s, start=0, end=len(s)):
... return s[start:end]
...
py func(function, start=1, end=5) # works correctly
unct
py func(ant) # default works correctly here
ant
py func(function) # default is broken here
func
py s = antidisestablishmentarianism
py func(s) # default is broken even when s changed
anti



-- 
Steven.

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Use cases for del

2005-07-06 Thread Jp Calderone
On Wed, 06 Jul 2005 09:45:56 -0400, Peter Hansen [EMAIL PROTECTED] wrote:
Tom Anderson wrote:
 How about just getting rid of del? Removal from collections could be
 done with a method call, and i'm not convinced that deleting variables
 is something we really need to be able to do (most other languages
 manage without it).

Arguing the case for del: how would I, in doing automated testing,
ensure that I've returned everything to a clean starting point in all
cases if I can't delete variables?  Sometimes a global is the simplest
way to do something... how do I delete a global if not with del?


Unless you are actually relying on the global name not being defined, 
someGlobal = None would seem to do just fine.

Relying on the global name not being defined seems like an edge case.

Jp
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Use cases for del

2005-07-06 Thread Daniel Dittmar
Peter Hansen wrote:
 Arguing the case for del: how would I, in doing automated testing, 
 ensure that I've returned everything to a clean starting point in all 
 cases if I can't delete variables?  Sometimes a global is the simplest 
 way to do something... how do I delete a global if not with del?

globals ().__delitem__ (varname)

except that the method would probably be called delete.

Daniel
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Use cases for del

2005-07-06 Thread Duncan Booth
Peter Hansen wrote:

 Tom Anderson wrote:
 How about just getting rid of del? Removal from collections could be 
 done with a method call, and i'm not convinced that deleting variables 
 is something we really need to be able to do (most other languages 
 manage without it).
 
 Arguing the case for del: how would I, in doing automated testing, 
 ensure that I've returned everything to a clean starting point in all 
 cases if I can't delete variables?  Sometimes a global is the simplest 
 way to do something... how do I delete a global if not with del?
 
I generally find that unit tests force me to structure the code in a 
cleaner manner, e.g. to not use globals as much, but if you do need to 
delete a global you do it in exactly the same way as you delete anything: 
use the del statement:

 x = 3
 def f():
global x
del x


 x
3
 f()
 x

Traceback (most recent call last):
  File pyshell#7, line 1, in -toplevel-
x
NameError: name 'x' is not defined
 

Where I have used 'del' in a unit test it has been to delete local 
variables rather than globals. Specifically I wanted to ensure that some 
data structures were being torn down properly, so the test went something 
like this:

setup: creates a weakref dictionary.

teardown: asserts that the weakref dictionary is empty.

then each test does:

  try:
create something
add it to the weakref dictionary
then test it
  finally:
use del to remove local variables
force a garbage collection

Without the del, when a test fails you get two failures, because the 
traceback information keeps the variables alive.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Use cases for del

2005-07-06 Thread Steven D'Aprano
On Wed, 06 Jul 2005 10:00:02 -0400, Jp Calderone wrote:

 On Wed, 06 Jul 2005 09:45:56 -0400, Peter Hansen [EMAIL PROTECTED] wrote:
Tom Anderson wrote:
 How about just getting rid of del? Removal from collections could be
 done with a method call, and i'm not convinced that deleting variables
 is something we really need to be able to do (most other languages
 manage without it).

Arguing the case for del: how would I, in doing automated testing,
ensure that I've returned everything to a clean starting point in all
cases if I can't delete variables?  Sometimes a global is the simplest
way to do something... how do I delete a global if not with del?

 
 Unless you are actually relying on the global name not being defined, 
 someGlobal = None would seem to do just fine.
 
 Relying on the global name not being defined seems like an edge case.

Er, there is a lot of difference between a name not existing and it being
set to None.

$ cat mymodule1.py

# define some temporary names
a, b, c, d, e, f = 1, 2, 3, 4, 5, 6
# do some work
result = a+b+c+d*e**f
# delete the temp variables
del a
del b
del c
del d
del e
del f

$ cat mymodule2.py

# define some temporary names
a, b, c, d, e, f = 1, 2, 3, 4, 5, 6
# do some work
result = a+b+c+d*e**f
# delete the temp variables
a = None
b = None
c = None
d = None
e = None
f = None

Now import them into Python:

py import mymodule1, mymodule2
py dir(mymodule1)
['__file__', '__name__', result]
py dir(mymodule2)
['__file__', '__name__', result, a, b, c, d, e, f]

Or worse, do this:

py a = 1
py from mymodule2 import *
py a + 1
Traceback (most recent call last):
  File stdin, line 1, in ?
TypeError: unsupported operand type(s) for +: 'NoneType' and 'int'

It is bad enough that from module import * can over-write your variables
with the modules' variables, but for it to do so with DELETED variables is
unforgivable.



-- 
Steven.

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Use cases for del

2005-07-06 Thread Ron Adam
Steven D'Aprano wrote:
 On Wed, 06 Jul 2005 10:00:02 -0400, Jp Calderone wrote:
 
 
On Wed, 06 Jul 2005 09:45:56 -0400, Peter Hansen [EMAIL PROTECTED] wrote:

Tom Anderson wrote:

How about just getting rid of del? Removal from collections could be
done with a method call, and i'm not convinced that deleting variables
is something we really need to be able to do (most other languages
manage without it).

Arguing the case for del: how would I, in doing automated testing,
ensure that I've returned everything to a clean starting point in all
cases if I can't delete variables?  Sometimes a global is the simplest
way to do something... how do I delete a global if not with del?


Unless you are actually relying on the global name not being defined, 
someGlobal = None would seem to do just fine.

Relying on the global name not being defined seems like an edge case.
 
 
 Er, there is a lot of difference between a name not existing and it being
 set to None.

Yes, they are not currently the same thing.


But what if assigning a name to None actually unbound it's name?


And accessing an undefined name returned None instead of a NameError?


Using an undefined name in most places will still generate some sort of 
an None type error.

I think the biggest drawback to this second suggestion is that we would 
have to test for None in places where it would matter, but that's 
probably a good thing and enables checking if a variable exists without 
using a try-except.


$ cat mymodule2.py

# define some temporary names
a, b, c, d, e, f = 1, 2, 3, 4, 5, 6
# do some work
result = a+b+c+d*e**f
# delete the temp variables
a = b = c = d = e = f = None# possibly unbind names

This would work if None unbound names.


 It is bad enough that from module import * can over-write your variables
 with the modules' variables, but for it to do so with DELETED variables is
 unforgivable.

Yes, I agree using None as an alternative to delete currently is 
unacceptable.

Cheers,
Ron
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Use cases for del

2005-07-06 Thread Stian Søiland
On 2005-07-06 18:10:16, Ron Adam wrote:

 But what if assigning a name to None actually unbound it's name?
 And accessing an undefined name returned None instead of a NameError?

Yes, and we can make 

someunknownlist[] = 2

magically do someunknownlist = list() and append 2.


Please.

-- 
Stian Søiland   Work toward win-win situation. Win-lose
Trondheim, Norway   is where you win and the other lose.
http://soiland.no/  Lose-lose and lose-win are left as an
exercise to the reader.  [Limoncelli/Hogan]
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Use cases for del

2005-07-06 Thread Benji York
Stian Søiland wrote:
 Yes, and we can make 
 
 someunknownlist[] = 2
 
 magically do someunknownlist = list() and append 2.

I hope you're being sarcastic.  :)

If not, why don't you like:

some_list = [2]
--
Benji York
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Use cases for del

2005-07-06 Thread Ron Adam
Ron Adam wrote:

 And accessing an undefined name returned None instead of a NameError?

I retract this.  ;-)

It's not a good idea.  But assigning to None as a way to unbind a name 
may still be an option.

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Use cases for del

2005-07-06 Thread Reinhold Birkenfeld
Ron Adam wrote:
 Ron Adam wrote:
 
 And accessing an undefined name returned None instead of a NameError?
 
 I retract this.  ;-)
 
 It's not a good idea.  But assigning to None as a way to unbind a name 
 may still be an option.

IMO, it isn't. This would completely preclude the usage of None as a value.
None is mostly used as a null value. The most prominent example is default
function arguments:

def foo(bar, baz=None):

With None unbinding the name, what would you suggest should happen? baz being
undefined in the function scope?

Or, what should happen for

somedict[1] = None

The same as

del somedict[1]

? Also, the concept of _assigning_ something to a name to actually _unassign_
the name is completely wrong.

Of course, this is a possible way to unassign names if (and only if)
(1) there is a real undefined value (not None)
(2) unbound names return the undefined value

Look at Perl. Do we want to be like that? ;)

Reinhold
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Use cases for del

2005-07-06 Thread Ron Adam
Reinhold Birkenfeld wrote:

 Ron Adam wrote:
 
Ron Adam wrote:


And accessing an undefined name returned None instead of a NameError?

I retract this.  ;-)

It's not a good idea.  But assigning to None as a way to unbind a name 
may still be an option.
 
 IMO, it isn't. This would completely preclude the usage of None as a value.
 None is mostly used as a null value. The most prominent example is default
 function arguments:
 
 def foo(bar, baz=None):
 
 With None unbinding the name, what would you suggest should happen? baz being
 undefined in the function scope?

It would be a way to set an argument as being optional without actually 
assigning a value to it.  The conflict would be if there where a global 
with the name baz as well.  Probably it would be better to use a valid 
null value for what ever baz if for.  If it's a string then , if its a 
number then 0, if it's a list then [], etc...

If it's an object... I suppose that would be None...  Oh well. ;-)

 Or, what should happen for
 
 somedict[1] = None

Remove the key of course.

   var = somedict[1]  Would then give an error.

and

   (somedict[1] == None)  Would evaluate to True.


 ? Also, the concept of _assigning_ something to a name to actually _unassign_
 the name is completely wrong.

That's not anymore wrong than ([] == [None]) -- False.

Having a None value remove a name binding could make the above condition 
True.

 Of course, this is a possible way to unassign names if (and only if)
 (1) there is a real undefined value (not None)
 (2) unbound names return the undefined value
 
 Look at Perl. Do we want to be like that? ;)
 
 Reinhold

The problem I had with perl is that number of symbols and ways of 
combining them can be quite confusing when you don't use it often.  So 
it's either a language you use all the time... or avoid.

Anyway, there seems to be enough subtle side effects both small and 
large to discount the idea.  While implementing it may be possible, it 
would require a number of other changes as well as a different way of 
thinking about it, so I expect it would be disliked quite a bit.

Cheers,
Ron
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Use cases for del

2005-07-06 Thread Grant Edwards
On 2005-07-06, Ron Adam [EMAIL PROTECTED] wrote:

 It would be a way to set an argument as being optional without actually 
 assigning a value to it.  The conflict would be if there where a global 
 with the name baz as well.  Probably it would be better to use a valid 
 null value for what ever baz if for.  If it's a string then , if its a 
 number then 0, if it's a list then [], etc...

Except those aren't null values for those types.  0 is a
perfectly good integer value, and I use it quite often. There's
a big difference between an invalid integer value and an
integer with value 0.

-- 
Grant Edwards   grante Yow!  I've read SEVEN
  at   MILLION books!!
   visi.com
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Use cases for del

2005-07-06 Thread Ron Adam
Grant Edwards wrote:

 On 2005-07-06, Ron Adam [EMAIL PROTECTED] wrote:
 
 
It would be a way to set an argument as being optional without actually 
assigning a value to it.  The conflict would be if there where a global 
with the name baz as well.  Probably it would be better to use a valid 
null value for what ever baz if for.  If it's a string then , if its a 
number then 0, if it's a list then [], etc...
 
 
 Except those aren't null values for those types.  0 is a
 perfectly good integer value, and I use it quite often. There's
 a big difference between an invalid integer value and an
 integer with value 0.

Why would you want to use None as an integer value?

If a value isn't established yet, then do you need the name defined? 
Wouldn't it be better to wait until you need the name then give it a value?



-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Use cases for del

2005-07-06 Thread Grant Edwards
On 2005-07-07, Ron Adam [EMAIL PROTECTED] wrote:
 Grant Edwards wrote:

 On 2005-07-06, Ron Adam [EMAIL PROTECTED] wrote:
 
 
It would be a way to set an argument as being optional without
actually assigning a value to it.  The conflict would be if
there where a global with the name baz as well.  Probably it
would be better to use a valid null value for what ever baz if
for.  If it's a string then , if its a number then 0, if it's
a list then [], etc...
 
 Except those aren't null values for those types.  0 is a
 perfectly good integer value, and I use it quite often. There's
 a big difference between an invalid integer value and an
 integer with value 0.

 Why would you want to use None as an integer value?

1) So I know whether an parameter was passed in or not. Perhaps
   it's not considered good Pythonic style, but I like to use a
   single method for both get and set operations.  With no
   parameters, it's a get.  With a parameter, it's a set:

   class demo:
  def foo(v=None):
  if v is not None:
  self.v = v
  return self.v  

2) So I can use it as sort of a NaN equivalent.

   if self.fd is None:
  self.fd = os.open('foo.bar','w')
   
   if self.fd is not None:
  os.close(self.fd)
  self.fd = None  

 If a value isn't established yet, then do you need the name
 defined?

I find it more obvious to set the name to None during the
periods that it isn't valid than to delete it and check for a
NameError when I want to know if the value is usable or not.

 Wouldn't it be better to wait until you need the name then
 give it a value?

Better is a value judgement.  I prefer setting it None and
than deleting it and then checking for existance.

-- 
Grant Edwards   grante Yow!  Hey, LOOK!! A pair of
  at   SIZE 9 CAPRI PANTS!! They
   visi.comprobably belong to SAMMY
   DAVIS, JR.!!
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Use cases for del

2005-07-06 Thread Leif K-Brooks
Grant Edwards wrote:
 1) So I know whether an parameter was passed in or not. Perhaps
it's not considered good Pythonic style, but I like to use a
single method for both get and set operations.  With no
parameters, it's a get.  With a parameter, it's a set:
 
class demo:
   def foo(v=None):
   if v is not None:
   self.v = v
   return self.v  

_NOVALUE = object()
class demo:
def foo(v=_NOVALUE):
if v is _NOVALUE:
return self.v
else:
self.v = v

But what's wrong with properties?
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Use cases for del

2005-07-06 Thread Grant Edwards
On 2005-07-07, Leif K-Brooks [EMAIL PROTECTED] wrote:

 Grant Edwards wrote:
 1) So I know whether an parameter was passed in or not. Perhaps
it's not considered good Pythonic style, but I like to use a
single method for both get and set operations.  With no
parameters, it's a get.  With a parameter, it's a set:
 
class demo:
   def foo(v=None):
   if v is not None:
   self.v = v
   return self.v  

 _NOVALUE = object()
 class demo:
 def foo(v=_NOVALUE):
 if v is _NOVALUE:
 return self.v
 else:
 self.v = v

Apart from the change in the logic such that the set operation
doesn't return a value, how is that any different?  You're just
creating your own non-integer-value None object instead of
using the one built in to the language.

 But what's wrong with properties?

Huh?

-- 
Grant Edwards   grante Yow!
  at   TAILFINS!!... click...
   visi.com
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Use cases for del

2005-07-06 Thread George Sakkis
Grant Edwards wrote:

 In 2005-07-07, Leif K-Brooks [EMAIL PROTECTED] wrote:

 - Hide quoted text -
 - Show quoted text -
  Grant Edwards wrote:
  1) So I know whether an parameter was passed in or not. Perhaps
 it's not considered good Pythonic style, but I like to use a
 single method for both get and set operations.  With no
 parameters, it's a get.  With a parameter, it's a set:

 class demo:
def foo(v=None):
if v is not None:
self.v = v
return self.v

  _NOVALUE = object()
  class demo:
  def foo(v=_NOVALUE):
  if v is _NOVALUE:
  return self.v
  else:
  self.v = v

 Apart from the change in the logic such that the set operation
 doesn't return a value, how is that any different?  You're just
 creating your own non-integer-value None object instead of
 using the one built in to the language.

  But what's wrong with properties?

 Huh?

I guess he means why not define foo as property:

class demo(object):
foo = property(fget = lambda self: self.v,
   fset = lambda self,v: setattr(self,'v',v))

d = demo()
d.foo = 3
print d.foo


George

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Use cases for del

2005-07-06 Thread Leif K-Brooks
Grant Edwards wrote:
 On 2005-07-07, Leif K-Brooks [EMAIL PROTECTED] wrote:
_NOVALUE = object()
class demo:
def foo(v=_NOVALUE):
if v is _NOVALUE:
return self.v
else:
self.v = v
 
 
 Apart from the change in the logic such that the set operation
 doesn't return a value, how is that any different?  You're just
 creating your own non-integer-value None object instead of
 using the one built in to the language.

Sorry, my mistake: for some reason, I misunderstood your message as
complaining that you couldn't do the same thing if you needed None to be
usable as a value too.

But what's wrong with properties?
 
 Huh?

Why not use a property
(http://www.python.org/2.2.1/descrintro.html#property) instead of a
special property-like method?
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Use cases for del

2005-07-06 Thread Grant Edwards
On 2005-07-07, George Sakkis [EMAIL PROTECTED] wrote:

 I guess he means why not define foo as property:

 class demo(object):
 foo = property(fget = lambda self: self.v,
fset = lambda self,v: setattr(self,'v',v))

 d = demo()
 d.foo = 3
 print d.foo

In some ways that's even cleaner.

In my simplivied example all the foo() method was doing was
setting/returning an attribute, but usually there's a bit more
going on (e.g. system calls with possible side effects).  

To me it's a bit more explicit that

  d.foo(3)
  d.foo()

are doing something other than just getting/setting the value
of an instance attribute.  If all I really wanted to do was
get/set the instance's v attribute, I probably would have
just done it like this

  d.v = 3
  print d.v  

-- 
Grant Edwards   grante Yow!  .. I wonder if I
  at   ought to tell them about my
   visi.comPREVIOUS LIFE as a COMPLETE
   STRANGER?
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Use cases for del

2005-07-06 Thread Grant Edwards
On 2005-07-07, Leif K-Brooks [EMAIL PROTECTED] wrote:
 Grant Edwards wrote:
 On 2005-07-07, Leif K-Brooks [EMAIL PROTECTED] wrote:
_NOVALUE = object()
class demo:
def foo(v=_NOVALUE):
if v is _NOVALUE:
return self.v
else:
self.v = v
 
 
 Apart from the change in the logic such that the set operation
 doesn't return a value, how is that any different?  You're just
 creating your own non-integer-value None object instead of
 using the one built in to the language.

 Sorry, my mistake: for some reason, I misunderstood your message as
 complaining that you couldn't do the same thing if you needed None to be
 usable as a value too.

Somebody had proposed eliminating None as a usable object and
people who use None now should just use 0, [], , or ()
depending on the type of the expected value.  I was providing
an example of where I would use None in a context where an
integer context and where 0 wasn't a good substitue.

But what's wrong with properties?
 
 Huh?

 Why not use a property
 (http://www.python.org/2.2.1/descrintro.html#property) instead of a
 special property-like method?

Habit and the desire to make it explicit that something more is
going on that just assigning or evaluating an instance's
attribute.

-- 
Grant Edwards   grante Yow!  I want EARS! I
  at   want two ROUND BLACK
   visi.comEARS to make me feel warm
   'n secure!!
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Use cases for del

2005-07-06 Thread Ron Adam
Grant Edwards wrote:

 On 2005-07-07, Ron Adam [EMAIL PROTECTED] wrote:
 
Grant Edwards wrote:


On 2005-07-06, Ron Adam [EMAIL PROTECTED] wrote:



It would be a way to set an argument as being optional without
actually assigning a value to it.  The conflict would be if
there where a global with the name baz as well.  Probably it
would be better to use a valid null value for what ever baz if
for.  If it's a string then , if its a number then 0, if it's
a list then [], etc...

Except those aren't null values for those types.  0 is a
perfectly good integer value, and I use it quite often. There's
a big difference between an invalid integer value and an
integer with value 0.

Why would you want to use None as an integer value?
 
 
 1) So I know whether an parameter was passed in or not. Perhaps
it's not considered good Pythonic style, but I like to use a
single method for both get and set operations.  With no
parameters, it's a get.  With a parameter, it's a set:
 
class demo:
   def foo(v=None):
   if v is not None:
   self.v = v
   return self.v   

You are really checking if v exists, so having it undefined in namespace 
  as the default is consistent with what you are doing.

As I said above...

 It would be a way to set an argument as being optional without
 actually assigning a value to it.

So it would still work like you expect even though v is not bound to 
anything.  Like I said the bigger problem is that globals will be 
visible and that would create a conflict.  Setting a value to None in a 
function hides globals of the same name.  That wouldn't happen if None 
unbound names as del does.

So you would need to use something else for that purpose I suppose, but 
that was why None became a literal in the first place, so maybe it's 
taking a step backwards.


 2) So I can use it as sort of a NaN equivalent.
 
if self.fd is None:
   self.fd = os.open('foo.bar','w')

if self.fd is not None:
   os.close(self.fd)
   self.fd = None  

It would still work as you expect.  A while back I suggested an 'also' 
for if that would do exactly that with only one test.  Nobody liked it.

  if self.fd is None:
 self.fd = os.open('foo.bar','w')
 # do something with self.fd

  also:
 os.close(self.fd)
 self.fd = None


If a value isn't established yet, then do you need the name
defined?
  
 I find it more obvious to set the name to None during the
 periods that it isn't valid than to delete it and check for a
 NameError when I want to know if the value is usable or not.

You would still be able to do that explicitly and it probably would be a 
good idea when you aren't sure if a name is left over from something else.

If a name is None, it means it's available and unassigned, so you don't 
have to check for a NameError.


Wouldn't it be better to wait until you need the name then
give it a value?
 
 Better is a value judgement.  I prefer setting it None and
 than deleting it and then checking for existance.

They would be the same in this case.  Setting it to None would delete it 
also.  And checking it for None will let you know it's available or if 
it has a value...

You are right that it's a value judgment.  I agree.  BTW, I'm sort of 
just exploring this a bit, not trying to argue it's any better than what 
we currently do.  I think it could work either way, but it would mean 
doing things in a different way also, not neccisarily a good idea.

Cheers,
Ron


-- 
http://mail.python.org/mailman/listinfo/python-list