Obtaining a callable class method object from a specific class

2008-04-10 Thread Nathan Duran
This is a contrived pseudocode example which has been broken out of a  
larger problem, so it may seem like a strange thing to want to do,  
but...

I have a group of objects which inherit (single) from a common base  
class like so:

---
class Root(object):
 @classmethod
 def CumulativeScore(cls, arg):
 #Ask every child class to
 #generate a score and add
 #them together
 cumulativescore = 0
 for base in cls.mro():
 cumulativescore += base.Score(arg)
 return cumulativescore
 #No Score method defined in Root so don't try to call one!

class BranchChild(Root):
 @classmethod
 def Score(cls, arg):
 return 1

class LeafChild(BranchChild):
 @classmethod
 def Score(cls, arg):
 return 3

class LeafChild2(BranchChild):
 pass
 #No Score method defined here, either!

---

The goal is to be able to call CumulativeScore(arg) on an instance of  
any of these objects (Root, Branch or Leaf) which will then chain  
calls (top down) to each subclass' Score method if (and only if) one  
is defined, returning the sum of all of these calls. Kinda like  
constructor chaining, only I don't want it to be explicit/cooperative  
because super() doesn't seem to work in classmethods and I want to  
reduce the amount of redundant boilerplate code in the subclasses  
(which will be numerous).

In order to do this I really need a way to ask LeafChild to give me  
*its* Score method *if* it has one of its own. I don't want its  
parent's method or its grandparent's method (until I get to them of  
course), just the one that's (optionally) defined in LeafChild, so  
getattr() and __dict__ are of no use to me. The only thing I've been  
able to find that actually works is inspect.classify_class_attrs().  
While it delivers the expected behavior, classify_class_attrs spews  
out a ton of superfluous information which I have to parse myself, and  
the method objects it returns in its tuples are not callable to boot.  
This leads to ugly looking code like this:

---
@classmethod
 def CumulativeScore(cls, arg):
 cumulativescore = 0
 mro = list(cls.mro())
 mro.reverse()
 for base in mro:
 matchfunc = [getattr(base, "Score") for attr in  
inspect.classify_class_attrs(base) if attr[0] == "Score" and attr[2]  
== base]
 if len(matchfunc) == 1:
 cumulativescore += matchfunc[0](arg)
 return cumulativescore
---

In looking through the inspect module's documentation, it seems as  
though getmembers() once offered the functionality I require, but no  
longer:

"Changed in version 2.2: im_class used to refer to the class that  
defined the method."

I've gotten the feeling from the Python documentation that  
classmethods are seen as third-class citizens, but they are  
unfortunately perfect for my needs, and it doesn't seem like this  
should be as complicated as it is. Is there a simpler, more elegant  
way to ask a class object if it has a particular method definition  
that I've missed somewhere? If not, why can't classify_class_attrs at  
least return a callable method object for me (yes, I've read the  
"unifying" paper)?

Thanks!


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


Re: Obtaining a callable class method object from a specific class

2008-04-10 Thread Nathan Duran

On Apr 10, 2008, at 1:25 PM, [EMAIL PROTECTED] wrote:
>  won't question why you want to do this...
> Here is a solution base on a metaclass, but it feels wrong.

> class MetaScore(type):
>def __new__(meta, name, bases, attrs):
>attrs.setdefault('score', score)
>return type.__new__(meta, name, bases, attrs)

So you're saying to get rid of the inherited __dict__ entry altogether  
when the class is defined? I'm worried that this might be somewhat  
problematic since there's actually quite a lot of metaclass interplay  
going on already that might lead to one stepping on another's toes,  
but I may give it a shot.

Some more digging with different keywords turned up this obscure nugget:

http://docs.python.org/ref/types.html

"When a user-defined method object is created by retrieving a class  
method object from a class or instance, its im_self attribute is the  
class itself (the same as the im_class attribute), and its  
im_funcattribute is the function object underlying the class method."

I was under the impression that these were completely unbound, but it  
looks like I was misinformed. This appears to do what I need it to,  
but further testing is in order:

matchfunc = getattr(base, "Score", None)
if matchfunc and matchfunc.im_self == base:
 score += matchfunc(arg)





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


Re: About __init__ and default arguments

2008-04-11 Thread Nathan Duran

On Apr 11, 2008, at 11:35 AM, [EMAIL PROTECTED] wrote:
> I'd like to assign the value of an attribute in __init__ as the  
> default
> value of an argument in a method.  See below:

Are you sure? You will not get fresh values with each call in Python  
as you would in other languages.

Why not just do

def franklin(self, keyword):
 if not keyword: keyword = self.default
 return "A %s in time saves nine." % (keyword)


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


Re: Advice on tools/technologies/books, etc.

2008-04-12 Thread Nathan Duran

On Apr 12, 2008, at 6:55 PM, [EMAIL PROTECTED] wrote:
> Will it be possible for me to put together an async site
> with only python?

Nope. Not until some browser embeds a Python interpreter in it anyway.  
Your primary choices are JavaScript and Flash.

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