Re: [Python-Dev] Defining properties - a use case for class decorators?

2005-10-19 Thread Nick Coghlan
Phillip J. Eby wrote:
 Note that a where or given statement like this could make it a 
 little easier to drop lambda.

I think the lambda will disappear in Py3k concept might have been what 
triggered the original 'where' statement discussion.

The idea was to be able to lift an arbitrary subexpression out of a function 
call or assignment statement without having to worry about affecting the 
surrounding namespace, and without distracting attention from the original 
statement. Basically, let a local refactoring *stay* local.

The discussion wandered fairly far afield from that original goal though.

One reason it fell apart was trying to answer the seemingly simple question 
What would this print?:

   def f():
  a = 1
  b = 2
  print 1, locals()
  print 3, locals() given:
  a = 2
  c = 3
  print 2, locals()
  print 4, locals()

Cheers,
Nick.

-- 
Nick Coghlan   |   [EMAIL PROTECTED]   |   Brisbane, Australia
---
 http://boredomandlaziness.blogspot.com
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


[Python-Dev] Defining properties - a use case for class decorators?

2005-10-19 Thread Jim Jewett
(In http://mail.python.org/pipermail/python-dev/2005-October/057409.html,)
Nick Coghlan suggested allowing attribute references as binding targets.

x = property(Property x (must be less than 5))

def x.get(instance):  ...

Josiah shivered and said it was hard to tell what was even intended, and
(in http://mail.python.org/pipermail/python-dev/2005-October/057437.html)
Nick agreed that it was worse than

x.get = f given:
def f(): ...

Could someone explain to me why it is worse?

I understand not wanting to modify object x outside of its definition.

I understand that there is some trickiness about instancemethods
and bound variables.

But these objections seem equally strong for both forms, as well
as for the current equivalent of

def f(): ...
x.get = f

The first form (def x.get) at least avoids repeating (or even creating)
the temporary function name.

The justification for decorators was to solve this very problem within
a module or class.  How is this different?  Is it just that attributes
shouldn't be functions, and this might encourage the practice?

-jJ
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] Defining properties - a use case for class decorators?

2005-10-19 Thread Phillip J. Eby
At 07:47 PM 10/19/2005 +1000, Nick Coghlan wrote:
Phillip J. Eby wrote:
  Note that a where or given statement like this could make it a
  little easier to drop lambda.

I think the lambda will disappear in Py3k concept might have been what
triggered the original 'where' statement discussion.

The idea was to be able to lift an arbitrary subexpression out of a function
call or assignment statement without having to worry about affecting the
surrounding namespace, and without distracting attention from the original
statement. Basically, let a local refactoring *stay* local.

The discussion wandered fairly far afield from that original goal though.

One reason it fell apart was trying to answer the seemingly simple question
What would this print?:

def f():
   a = 1
   b = 2
   print 1, locals()
   print 3, locals() given:
   a = 2
   c = 3
   print 2, locals()
   print 4, locals()

It would print SyntaxError, because the 'given' or 'where' clause should 
only work on an expression or assignment statement, not print.  :)

In Python 3000, where print is a function, it should print the numbers in 
sequence, with 1+4 showing the outer locals, and 2+3 showing the inner 
locals (not including 'b', since b is not a local variable in the nested 
block).

I don't see what's hard about the question, if you view the block as syntax 
sugar for a function definition and invocation on the right hand side of an 
assignment.

Of course, if you assume it can occur on *any* statement (e.g. print), I 
suppose things could seem more hairy.

___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] Defining properties - a use case for class decorators?

2005-10-19 Thread Josiah Carlson

Jim Jewett [EMAIL PROTECTED] wrote:
 (In http://mail.python.org/pipermail/python-dev/2005-October/057409.html,)
 Nick Coghlan suggested allowing attribute references as binding targets.
 
 x = property(Property x (must be less than 5))
 
 def x.get(instance):  ...
 
 Josiah shivered and said it was hard to tell what was even intended, and
 (in http://mail.python.org/pipermail/python-dev/2005-October/057437.html)
 Nick agreed that it was worse than
 
 x.get = f given:
 def f(): ...
 
 Could someone explain to me why it is worse?

def x.get(...): ...

Seems to imply that one is defining a method on x.  This is not the case.
It is also confused by the x.get(instance) terminology that I doubt has
ever seen light of day in production code.  Instance of what?  Instance
of x?  The class?  ...

I'm personally averse to the 'given:' syntax, if only because under
certain situations, it can be reasonably emulated.


 I understand not wanting to modify object x outside of its definition.
 
 I understand that there is some trickiness about instancemethods
 and bound variables.
 
 But these objections seem equally strong for both forms, as well
 as for the current equivalent of
 
 def f(): ...
 x.get = f
 
 The first form (def x.get) at least avoids repeating (or even creating)
 the temporary function name.
 
 The justification for decorators was to solve this very problem within
 a module or class.  How is this different?  Is it just that attributes
 shouldn't be functions, and this might encourage the practice?

Many will agree that there is a problem with how properties are defined.
There are many proposed solutions, some of which use decorators, custom
subclasses, metaclasses, etc.

I have a problem with it because from the description, you could use...

def x.y.z.a.b.c.foobarbaz(...):
...

...and it woud be unclear to the reader or writer what the hell
x.y.z.a.b.c is (class, instance, module), which can come up if the
definition/import of x is far enough away from the definition of
x.blah .  Again, ick.

 - Josiah

___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


[Python-Dev] Defining properties - a use case for class decorators?

2005-10-18 Thread Jim Jewett
Greg Ewing wrote:

 ... the standard way of defining properties at the moment
 leaves something to be desired, for all the same reasons
 that have led to @-decorators.

Guido write:

 ... make that feeling more concrete. ...

 With decorators there was a concrete issue: the modifier
 trailed after the function body, in a real sense hiding
 from the reader. I don't see such an issue with properties.

For me, the property declaration (including the function
declarations) is too verbose, and ends up hiding the rest
of the class.  My ideal syntax would look something like:

# Declare x to name a property.  Create a storage slot,
# with the generic get/set/del/doc.  (doc == property x?)
property(x)

# Change the setter, possibly in a subclass
property(x) set:
if x5:
__x = x

If I don't want anything special on the get, I shouldn't have
to add any get boilerplate to my code.

An alternative might be

slots=[x, y, z]

to automatically create default properties for x, y, and z,
while declaring that instances won't have arbitrary fields.

That said, I'm not sure the benefit is enough to justify the
extra complications, and your suggestion of allowing strings
for method names may be close enough.  I agree that the
use of strings is awkward, but ... probably no worse than
using them with __dict__ today.

-jJ
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] Defining properties - a use case for class decorators?

2005-10-18 Thread Nick Coghlan
Jim Jewett wrote:
 That said, I'm not sure the benefit is enough to justify the
 extra complications, and your suggestion of allowing strings
 for method names may be close enough.  I agree that the
 use of strings is awkward, but ... probably no worse than
 using them with __dict__ today.

An idea that was kicked around on c.l.p a long while back was statement local 
variables, where you could define some extra names just for a single simple 
statement:

   x = property(get, set, delete, doc) given:
   doc = Property x (must be less than 5)
   def get(self):
   try:
   return self._x
   except AttributeError:
   self._x = 0
   return 0
   def set(self, value):
   if value = 5: raise ValueError(value too big)
   self._x = x
   def delete(self):
   del self._x

As I recall, the idea died due to problems with figuring out how to allow the 
simple statement to both see the names from the nested block and modify the 
surrounding namespace, but prevent the names from the nested block from 
affecting the surrounding namespace after the statement was completed.

Another option would be to allow attribute reference targets when binding 
function names:

   x = property(Property x (must be less than 5))

   def x.get(instance):
   try:
   return instance._x
   except AttributeError:
   instance._x = 0
   return 0
   def x.set(instance, value):
   if value = 5: raise ValueError(value too big)
   instance._x = x

   def x.delete(instance):
   del instance._x

Cheers,
Nick.

-- 
Nick Coghlan   |   [EMAIL PROTECTED]   |   Brisbane, Australia
---
 http://boredomandlaziness.blogspot.com
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] Defining properties - a use case for class decorators?

2005-10-18 Thread Phillip J. Eby
At 11:59 PM 10/18/2005 +1000, Nick Coghlan wrote:
An idea that was kicked around on c.l.p a long while back was statement 
local
variables, where you could define some extra names just for a single simple
statement:

x = property(get, set, delete, doc) given:
doc = Property x (must be less than 5)
def get(self):
try:
return self._x
except AttributeError:
self._x = 0
return 0
...

As I recall, the idea died due to problems with figuring out how to allow the
simple statement to both see the names from the nested block and modify the
surrounding namespace, but prevent the names from the nested block from
affecting the surrounding namespace after the statement was completed.

Haskell's where statement does this, but the block *doesn't* modify the 
surrounding namespace; it's strictly local.  With those semantics, the 
Python translation of the above could just be something like:

 def _tmp():
doc = blah
def get(self):
# etc.
# ...
return property(get,set,delete,doc)

 x = _tmp()

Which works great except for the part that co_lnotab won't let you identify 
that return line as being the original expression line, due to the 
monotonically-increasing bit.  ;)

Note that a where or given statement like this could make it a little 
easier to drop lambda.

___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] Defining properties - a use case for class decorators?

2005-10-18 Thread Josiah Carlson

Nick Coghlan [EMAIL PROTECTED] wrote:
 
 Jim Jewett wrote:
  That said, I'm not sure the benefit is enough to justify the
  extra complications, and your suggestion of allowing strings
  for method names may be close enough.  I agree that the
  use of strings is awkward, but ... probably no worse than
  using them with __dict__ today.
 
 An idea that was kicked around on c.l.p a long while back was statement 
 local 
 variables, where you could define some extra names just for a single simple 
 statement:
 
x = property(get, set, delete, doc) given:
doc = Property x (must be less than 5)
def get(self):
try:
return self._x
except AttributeError:
self._x = 0
return 0
def set(self, value):
if value = 5: raise ValueError(value too big)
self._x = x
def delete(self):
del self._x
 
 As I recall, the idea died due to problems with figuring out how to allow the 
 simple statement to both see the names from the nested block and modify the 
 surrounding namespace, but prevent the names from the nested block from 
 affecting the surrounding namespace after the statement was completed.

You wouldn't be able to write to the surrounding namespace, but a
closure would work fine for this.

def Property(fcn):
ns = fcn()
return property(ns.get('get'), ns.get('set'), ns.get('delete'), 
ns.get('doc'))

class foo(object):
@Property
def x():
doc = Property x (must be less than 5)
def get(self):
try:
return self._x
except AttributeError:
self._x = 0
return 0
def set(self, value):
if value = 5: raise ValueError(value too big)
self._x = value
def delete(self):
del self._x
return locals()

In an actual 'given:' statement, one could create a local function
namespace with the proper func_closure attribute (which is automatically
executed), then execute the lookup of the arguments to the statement in
the 'given:' line from this closure, but assign to surrounding scope.
Then again, maybe the above function and decorator approach are better.


An unfortunate side-effect of with statement early-binding of 'as VAR'
is that unless one works quite hard at mucking about with frames, the
following has a wholly ugly implementation (whether or not one cares
about the persistance of the variables defined within the block, you
still need to modify x when you are done, which may as well cause a
cleanup of the objects defined within the block...if such things are
possible)...

with Property as x:
...


 Another option would be to allow attribute reference targets when binding 
 function names:

*shivers at the proposal*  That's scary.  It took me a few minutes just
to figure out what the heck that was supposed to do.

 - Josiah

___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com