Re: [Tutor] Using new style classes and __slots__

2005-09-25 Thread Liam Clarke
 Oh wait, I get it - you are passing bound methods to property(). So um is 
 bound to the instance when you access self.getA. Use Strange.getA instead of 
 self.getA, then use the normal signatures.

Ahh... I get it.

 But I don't get why you are doing this at all?

Because some of the objects I'm working with have 65 attributes, each
one needs to be typechecked and then passed down the line. As the
knowledge of the file structure I'm reading is not complete, as it
changes I'll have to update it. At the moment, what I'm doing is I
have a  docstring like so -

Type: Track Item

Tuple format:
[0]   header_id (4string)
[1]   header_length (int)
[2]   total_length (int)-- (Of child 
strings + header)
[3]   num_of_strings (int)  -- (Above 
child strings)
... ...
[62] unknown (int)
[63] unknown (int)
[64] unknown (int)



and a struct string 4s6ih2c7i2h12iq2c3h10iq17i

Now, as knowledge of the format changes, so does that tuple format and
struct string.
I have a convenience function which parses my docstring for each class
and creates a module dictionary of attribute name, type and length if
applicable. It can also create a struct string based on those types. I
can then call a generic set for all those attributes, which will pull
the type out of the dict and check it, and also acts as a repository
for attribute names.

If the file structure changes, I simply update my doc string, call my
convenience function, and my name:type dictionary is updated, as is my
struct string.

Alternatively, I can manually add header_id = property(..) and
manually update the struct string and the doc string when something
changes.

However, on reflection, I just figured out that it'll be simpler using
__setattr__ for this one, as I won't be able to get the attribute name
using property() unless I use a function factory to generate 127
functions and use func.__name__, when using __setattr__ and a
dictionary lookup is going to be much simpler.

But, it's good to know how to use property. I can think of a couple of
uses it for it. I wasn't thinking far enough ahead in this case, so
please forgive my emailed meanderings.

 It is passing self twice, because you are using a bound method as the 
 property method
 rather than an unbound method.

Erk. That seems obvious in hindsight, like a cryptic crossword answer.
Once again, my lack of experience with this sorta stuff comes up.

I've never really dealt with indepth oo stuff before, so this has all
been a gigantic learning curve. Thanks for your help on this, Kent.

 This is a hassle for me because I'm a lazy typist, so I've been using
 setattr() to pull attribute names out of a list. And the first
 argument setattr() requires is an object, and self doesn't work
 outside of a method, and using the class name leads to no attribute
 being set.

I don't understand this at all, can you give an example?

Basically, I just found that outside methods, self gives a
NameError. The examples are all needless now, anyway.

Regards,

Liam Clarke
___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Using new style classes and __slots__

2005-09-24 Thread Liam Clarke
Hi,


 You might want to learn more about the whole property mechanism then. 
 property() is actually a bit of sugar over a deeper mechanism. Also there is 
 an interesting idiom for creating properties using @apply (in Python 2.4) - 
 look for Benji York's comment in this recipe:
 http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/410698

Thanks Kent. Just looking at that above recipe, I'm not too sure how
the @ decorators work.
From what I understand, it defines would turn apply() into a function
that returns the various get/sets?

Also found something interesting with property(), if it's called in
__init__ you get
 a.a
property object at 0x011598C8

whereas called outside __init__ it works normally.

This is a hassle for me because I'm a lazy typist, so I've been using
setattr() to pull attribute names out of a list. And the first
argument setattr() requires is an object, and self doesn't work
outside of a method, and using the class name leads to no attribute
being set.

Hmm, may have to learn even more about classes and their internals.

Regards,

Liam Clarke
___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Using new style classes and __slots__

2005-09-24 Thread Liam Clarke
Ooer,

Well, I got setattr() and property() working together nicely, but with
a weird side effect.

class Strange(object):
def getA(um, self):
print What is, um
return self.__a

def setA(um, self, value):
print um, turns up here as well.
self.__a = value

def __init__(self):
setattr(Strange, a, property(self.getA, self.setA))
self.a = 20

 c = Strange()
__main__.Strange object at 0x01166290 turns up here as well.
 print c.a
What is __main__.Strange object at 0x01166290
20
 c
__main__.Strange object at 0x01166290

To my uneducated eye, it looks like it's passing self twice! Returning
um.__a works exactly the same as self.__a!

I'm getting the feelin I may need to venture into comp.lang.Python
with this sort of stuff.

Interesting.

Liam Clarke

On 9/25/05, Liam Clarke [EMAIL PROTECTED] wrote:
 Hi,


  You might want to learn more about the whole property mechanism then. 
  property() is actually a bit of sugar over a deeper mechanism. Also there 
  is an interesting idiom for creating properties using @apply (in Python 
  2.4) - look for Benji York's comment in this recipe:
  http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/410698

 Thanks Kent. Just looking at that above recipe, I'm not too sure how
 the @ decorators work.
 From what I understand, it defines would turn apply() into a function
 that returns the various get/sets?

 Also found something interesting with property(), if it's called in
 __init__ you get
  a.a
 property object at 0x011598C8

 whereas called outside __init__ it works normally.

 This is a hassle for me because I'm a lazy typist, so I've been using
 setattr() to pull attribute names out of a list. And the first
 argument setattr() requires is an object, and self doesn't work
 outside of a method, and using the class name leads to no attribute
 being set.

 Hmm, may have to learn even more about classes and their internals.

 Regards,

 Liam Clarke

___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Using new style classes and __slots__

2005-09-24 Thread Kent Johnson
Liam Clarke wrote:
http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/410698
 
 
 Thanks Kent. Just looking at that above recipe, I'm not too sure how
 the @ decorators work.
From what I understand, it defines would turn apply() into a function
 that returns the various get/sets?

OK, lets pick it apart a bit. Here is the recipe for defining a property:
class Example(object):
@apply
def myattr():
doc = This is the doc string.

def fget(self):
return self._value

def fset(self, value):
self._value = value

def fdel(self):
del self._value

return property(**locals())

Looking at myattr(), it defines the four attributes that make a property - doc, 
fget, fset and fdel. So at the end of myattr(), locals() is a dictionary 
containing these four attributes. Then it calls property() and passes it 
locals() as keyword arguments. So the last line is the same as return 
property(doc=doc, fget=fget, fset=fset, fdel=fdel) which creates a normal 
property.

OK, now what does the @apply do? Well, it's a decorator, and in general
@some_decorator
def myfunc():
  # etc

means the same thing as
def myfunc():
  # etc
myfunc = some_decorator(myfunc)

In other words the decorator is called with the function as an argument, and 
the return value of the function is bound to the name of the original function. 
So we have to know what apply(myattr) does. Actually, it just calls myattr(). 
So the net result is
myattr = myattr() i.e.
myattr = property(doc=doc, fget=fget, fset=fset, fdel=fdel)
which is what you would have done any way if you weren't trying to be so clever.

What does this recipe buy you? It puts the property function definitions into a 
separate namespace so they are not accessible as member functions, and it lets 
you reuse the names for them instead of having to invent new ones each time.
 
 Also found something interesting with property(), if it's called in
 __init__ you get
 
a.a
 
 property object at 0x011598C8
 
 whereas called outside __init__ it works normally.

Are you assigning the property to self or to the class? It might work if you 
assign to the class. But you will be recreating the properties for every 
instance.
 
 This is a hassle for me because I'm a lazy typist, so I've been using
 setattr() to pull attribute names out of a list. And the first
 argument setattr() requires is an object, and self doesn't work
 outside of a method, and using the class name leads to no attribute
 being set.

I don't understand this at all, can you give an example?
 
 Hmm, may have to learn even more about classes and their internals.

Yeah, it sounds like maybe a case for a metaclass.

Kent

 
 Regards,
 
 Liam Clarke
 ___
 Tutor maillist  -  Tutor@python.org
 http://mail.python.org/mailman/listinfo/tutor
 
 

___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Using new style classes and __slots__

2005-09-24 Thread Kent Johnson
Your method signatures are off. Should be
def getA(self):
def setA(self, value)

So when you write self.a = 20 you are passing self as the um parameter. 
Actually I don't know why you don't get an exception for passing too many 
arguments?

And you don't need setattr, just write
Strange.a = property(...)

Oh wait, I get it - you are passing bound methods to property(). So um is bound 
to the instance when you access self.getA. Use Strange.getA instead of 
self.getA, then use the normal signatures.

But I don't get why you are doing this at all? What does it buy you over the 
standard form of

class Normal(object):
def getA(self):
return self.__a

def setA(self, value):
self.__a = value

a = property(getA, setA)

def __init__(self):
self.a = 20

One more note below.

Kent

Liam Clarke wrote:
 Ooer,
 
 Well, I got setattr() and property() working together nicely, but with
 a weird side effect.
 
 class Strange(object):
 def getA(um, self): 
 print What is, um
 return self.__a
 
 def setA(um, self, value):
 print um, turns up here as well.
 self.__a = value
 
 def __init__(self):
 setattr(Strange, a, property(self.getA, self.setA))
 self.a = 20
 
 
c = Strange()
 
 __main__.Strange object at 0x01166290 turns up here as well.
 
print c.a
 
 What is __main__.Strange object at 0x01166290
 20
 
c
 
 __main__.Strange object at 0x01166290
 
 To my uneducated eye, it looks like it's passing self twice! Returning
 um.__a works exactly the same as self.__a!

It is passing self twice, because you are using a bound method as the property 
method rather than an unbound method.

 
 I'm getting the feelin I may need to venture into comp.lang.Python
 with this sort of stuff.
 
 Interesting.
 
 Liam Clarke
 
 On 9/25/05, Liam Clarke [EMAIL PROTECTED] wrote:
 
Hi,



You might want to learn more about the whole property mechanism then. 
property() is actually a bit of sugar over a deeper mechanism. Also there is 
an interesting idiom for creating properties using @apply (in Python 2.4) - 
look for Benji York's comment in this recipe:
http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/410698

Thanks Kent. Just looking at that above recipe, I'm not too sure how
the @ decorators work.
From what I understand, it defines would turn apply() into a function
that returns the various get/sets?

Also found something interesting with property(), if it's called in
__init__ you get

a.a

property object at 0x011598C8

whereas called outside __init__ it works normally.

This is a hassle for me because I'm a lazy typist, so I've been using
setattr() to pull attribute names out of a list. And the first
argument setattr() requires is an object, and self doesn't work
outside of a method, and using the class name leads to no attribute
being set.

Hmm, may have to learn even more about classes and their internals.

Regards,

Liam Clarke

 
 ___
 Tutor maillist  -  Tutor@python.org
 http://mail.python.org/mailman/listinfo/tutor
 
 

___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor