Re: Perl vs. Python question...

2009-07-14 Thread Lloyd Kvam
On Mon, 2009-07-13 at 22:59 -0400, Paul Lussier wrote:
 Lloyd Kvam pyt...@venix.com writes:
 
  You've already gotten two useful responses.  I'd just like to add that
  typically, the object attributes are referenced directly:
  rect.length * rect.width
 
 Lloyd, thanks. But what if the attribute isn't set yet?  If I have
 self.foo, and self.foo hasn't yet been set, I want it to go and get set,
 then return the correct value.

If the initial set value is a simple constant, make it a class attribute
with the default value.  The object can override the attribute with a
different value when that value is determined.
 
 I get the impression the __getattr__() method helps here, 

If the value will be computed on demand, __getattr__ is one way to go.
def __getattr__(self, attr):
if attr == 'foo':
return self.compute_foo()
elif 
else:
raise AttributeError( attr + ' is invalid name')

This is the 'traditional' approach.  __getattr__ is *only* called when
an attribute is not found.  If you wanted to save the computed value, so
that __getattr__ was no longer used:
self.__dict__['foo'] = self.compute_foo()
return self.foo

The simplistic self.foo = self.compute_foo() will trigger a call to
__getattr__, so you can't use that within __getattr__.


The new-style python classes allow for cleaner dispatching of your
attribute computations using properties, but for a small number of
names, __getattr__ will do just fine.  If there is no setter method and
foo is always computed, your class could be coded:

foo = property( compute_foo)

 I just don't
 quite get it yet.

HTH
 
 --
 Thanks,
 Paul
-- 
Lloyd Kvam
Venix Corp
DLSLUG/GNHLUG library
http://dlslug.org/library.html
http://www.librarything.com/catalog/dlslug
http://www.librarything.com/rsshtml/recent/dlslug
http://www.librarything.com/rss/recent/dlslug

___
gnhlug-discuss mailing list
gnhlug-discuss@mail.gnhlug.org
http://mail.gnhlug.org/mailman/listinfo/gnhlug-discuss/


Re: Perl vs. Python question...

2009-07-14 Thread Paul Lussier
Lloyd Kvam pyt...@venix.com writes:

 If the value will be computed on demand, __getattr__ is one way to go.
 def __getattr__(self, attr):
 if attr == 'foo':
 return self.compute_foo()
 elif 
 else:
 raise AttributeError( attr + ' is invalid name')

 This is the 'traditional' approach.  __getattr__ is *only* called when
 an attribute is not found.  If you wanted to save the computed value, so
 that __getattr__ was no longer used:
   self.__dict__['foo'] = self.compute_foo()
   return self.foo

 HTH

Very much so!

--
Thanks,
Paul
___
gnhlug-discuss mailing list
gnhlug-discuss@mail.gnhlug.org
http://mail.gnhlug.org/mailman/listinfo/gnhlug-discuss/


Re: Perl vs. Python question...

2009-07-14 Thread Lloyd Kvam
On Tue, 2009-07-14 at 15:32 -0400, Joshua Judson Rosen wrote:
  The simplistic self.foo = self.compute_foo() will trigger a call to
  __getattr__, so you can't use that within __getattr__.
 
 That's not true; it *will*, however, trigger a call to __settattr__,
 if it exists; that's what you're thinking of :)
 
 cf. http://docs.python.org/reference/datamodel.html#object.__setattr__
 
 __getattr__, however, is free to just do `self.foo = ...'.

Thanks for the correction.

-- 
Lloyd Kvam
Venix Corp
DLSLUG/GNHLUG library
http://dlslug.org/library.html
http://www.librarything.com/catalog/dlslug
http://www.librarything.com/rsshtml/recent/dlslug
http://www.librarything.com/rss/recent/dlslug

___
gnhlug-discuss mailing list
gnhlug-discuss@mail.gnhlug.org
http://mail.gnhlug.org/mailman/listinfo/gnhlug-discuss/


Re: Perl vs. Python question...

2009-07-13 Thread Lloyd Kvam
On Sat, 2009-07-11 at 23:44 -0400, Paul Lussier wrote:
 How do I create dynamically created methods in python classes?
 
 For example, if I have a number of member variables which I want to
 get
 or set, I don't want to have to create getters and setters for each
 attribute, since the code would largely be the same, just the variable
 I'm dealing with would be different.

You've already gotten two useful responses.  I'd just like to add that
typically, the object attributes are referenced directly:
rect.length * rect.width
to compute area.  Do not use: rect.get_length() * rect.get_width().

getter/setter methods get created when you some code is needed to
control access:
room.celsius
room.fahrenheit
computes the proper value from a single stored temperature (in Kelvin?).
The code still looks like a direct reference to the attribute.  You have
a choice of using __getattr__/__getattribute__/__setattr__ 
or properties as suggested in the other email responses.

-- 
Lloyd Kvam
Venix Corp
DLSLUG/GNHLUG library
http://dlslug.org/library.html
http://www.librarything.com/catalog/dlslug
http://www.librarything.com/rsshtml/recent/dlslug
http://www.librarything.com/rss/recent/dlslug

___
gnhlug-discuss mailing list
gnhlug-discuss@mail.gnhlug.org
http://mail.gnhlug.org/mailman/listinfo/gnhlug-discuss/


Re: Perl vs. Python question...

2009-07-13 Thread Bill McGonigle
On 07/11/2009 11:44 PM, Paul Lussier wrote:
 In perl, I can use the AUTOLOAD feature to dynamically create methods,
 something like this:

It looks like in perl6 you get this for free.  I'm just getting started
with it though.

-Bill

-- 
Bill McGonigle, Owner   Work: 603.448.4440
BFC Computing, LLC  Home: 603.448.1668
http://www.bfccomputing.com/Cell: 603.252.2606
Twitter, etc.: bill_mcgonigle   Page: 603.442.1833
Email, IM, VOIP: b...@bfccomputing.com
Blog: http://blog.bfccomputing.com/
VCard: http://bfccomputing.com/vcard/bill.vcf
___
gnhlug-discuss mailing list
gnhlug-discuss@mail.gnhlug.org
http://mail.gnhlug.org/mailman/listinfo/gnhlug-discuss/


Re: Perl vs. Python question...

2009-07-13 Thread Paul Lussier
Lloyd Kvam pyt...@venix.com writes:

 You've already gotten two useful responses.  I'd just like to add that
 typically, the object attributes are referenced directly:
 rect.length * rect.width

Lloyd, thanks. But what if the attribute isn't set yet?  If I have
self.foo, and self.foo hasn't yet been set, I want it to go and get set,
then return the correct value.

I get the impression the __getattr__() method helps here, I just don't
quite get it yet.

--
Thanks,
Paul
___
gnhlug-discuss mailing list
gnhlug-discuss@mail.gnhlug.org
http://mail.gnhlug.org/mailman/listinfo/gnhlug-discuss/


Re: Perl vs. Python question...

2009-07-12 Thread Joshua Judson Rosen
Paul Lussier p.luss...@comcast.net writes:

 Hi Folks,
 
 How do I create dynamically created methods in python classes?
 
 For example, if I have a number of member variables which I want to get
 or set, I don't want to have to create getters and setters for each
 attribute, since the code would largely be the same, just the variable
 I'm dealing with would be different.

Rather than implementing a whole bunch of similar `get_*()' and
`set_*()' methods in Python, you can just define __getattr__() and
__setattr__():

http://docs.python.org/reference/datamodel.html#object.__getattr__

How's that? Perfect fit? :)

Alternately (e.g.: something other than `getters and setters'): can't
you just create a single method that takes an `extra' parameter?

Even if you really do really want to `lots of methods' interface, I'd
still start with unified dispatcher-method--then the other methods
would just be simple wrappers, e.g.:

class C:
def do_stuff(self, key, *args):
   print 'doing %s stuff...' % key

do_x = lambda self, *args: self.do_stuff('x', *args)
do_y = lambda self, *args: self.do_stuff('y', *args)
do_z = lambda self, *args: self.do_stuff('z', *args)


You could even set all of those `C.do_*' attributes (which become
methods) automatically, e.g.:

for key in ('xray', 'yankee', 'zulu'):
def do_predispatched_stuff_stuff(self, *args):
return self.do_stuff(key, *rags)

setattr(C, key, do_predispatched_stuff)

-- 
Don't be afraid to ask (Lf.((Lx.xx) (Lr.f(rr.
___
gnhlug-discuss mailing list
gnhlug-discuss@mail.gnhlug.org
http://mail.gnhlug.org/mailman/listinfo/gnhlug-discuss/


Re: Perl vs. Python question...

2009-07-12 Thread Steven W. Orr
-BEGIN PGP SIGNED MESSAGE-
Hash: SHA1

On 07/11/09 23:44, quoth Paul Lussier:
 Hi Folks,
 
 How do I create dynamically created methods in python classes?
 
 For example, if I have a number of member variables which I want to get
 or set, I don't want to have to create getters and setters for each
 attribute, since the code would largely be the same, just the variable
 I'm dealing with would be different.
 
 In perl, I can use the AUTOLOAD feature to dynamically create methods,
 something like this:
 
   sub AUTOLOAD {
 my ($self, @args) = @_;
 my $method = $AUTOLOAD;
 $method =~ s/.*:://;
 if ($method ne 'DESTROY') {
   # Return the structure/value pointed to by $self-{KEY}, or, set it
   # if it's not a ref to something else.
   if (exists $self-{_$method}  !ref($self-{_$method})) {
 eval(*$AUTOLOAD = 
  . sub {
.   my (\$self, \$value) = assertMinMaxArgs(1, 2, \...@_);
  .   if (\$value) {
  . \$self-{\_\$method\} = \$value;
  .   }
  .   return \$self-{\_\$method\}
  . });
   }
   goto $AUTOLOAD;
 }
   }
 
 What this AUTOLOAD sub does is this:
 
  - First, it strips everything before the :: leaving just the methodname
(in perl, method names look like: CLASS::method() )
  - Then, it looks to see if there exists a member variable
$self-{_foo}, and that it's not a reference to something
  - Then, it creates an anonymous sub (== a lambda in python I think)
Each anonymous sub looks like this:
 
 sub {
   my ($self, $value) = assertMinMaxArgs(1, 2, @_);
   if ($value) {
  $self-{_$method} = $value;
   }
   return $self-{_$method}
 
 Essentially, it works like this.  If I have a member variable _foo, and
 I want to either set or get _foo, I call a method $self-foo().  If I
 call it as $self-foo(bar), the _foo gets set to bar, otherwise, I get
 back the current value of _foo.  So, the anonymous sub above, gets
 re-written as:
 
 sub foo {
   my ($self, $value) = assertMinMaxArgs(1, 2, @_);
   if ($value) {
  $self-{_foo} = $value;
   }
   return $self-{_foo}
 
 I can basically create 1 method which will automagically create for me,
 getter and setter methods for any member variable I create in my class.
 (this is extremely similar, if not identical, to lisp macros!)
 
 For some reason I didn't think python had this capability, but someone
 mentioned to me it did, but I'm not quite sure how I'd write it.
 
 Does anyone have any ideas?

In the Python Coookbook, on (my) page 252 is a section called Section 6.8:
Avoiding Boilerplate Accessors for Properties.

http://www.ubookcase.com/book/Oreilly/Python.Cookbook.2nd.edition/0596007973/pythoncook2-chp-6-sect-8.html

The code they provide is this:

def xproperty(fget, fset, fdel=None, doc=None):
if isinstance(fget, str):
attr_name = fget
def fget(obj): return getattr(obj, attr_name)
elif isinstance(fset, str):
attr_name = fset
def fset(obj, val): setattr(obj, attr_name, val)
else:
raise TypeError, 'either fget or fset must be a str'
return property(fget, fset, fdel, doc)

but the discussion is important to read and fully understand before you think
you can just plug it in.

- --
Time flies like the wind. Fruit flies like a banana. Stranger things have  .0.
happened but none stranger than this. Does your driver's license say Organ ..0
Donor?Black holes are where God divided by zero. Listen to me! We are all- 000
individuals! What if this weren't a hypothetical question?
steveo at syslang.net
-BEGIN PGP SIGNATURE-
Version: GnuPG v2.0.10 (GNU/Linux)
Comment: Using GnuPG with Fedora - http://enigmail.mozdev.org

iEYEARECAAYFAkpaP+kACgkQRIVy4fC+NyRqtQCeLV5oscJqOGQ0zME7KXjvM8n2
HZsAn1OcpB0aif6K1rTbchwdV7GDzn7k
=gJni
-END PGP SIGNATURE-
___
gnhlug-discuss mailing list
gnhlug-discuss@mail.gnhlug.org
http://mail.gnhlug.org/mailman/listinfo/gnhlug-discuss/