Unification of Methods and Functions
Michele Simionato
michele.simionato at poste.it
Fri May 14 00:43:30 EDT 2004
David MacQuigg <dmq at gain.com> wrote in message news:<utfh90li0r88p4ea8j1d9891ldm5n4fcki at 4ax.com>...
>
> ## This does not:
> uf = Cat.talk # Save an unbound function.
> uf() #=>
> # AttributeError: type object 'Cat' has no attribute 'name'
>
> I would like to be able to do something like:
> __self__ = cat2
> uf()
So, if I understand correcly, you want Cat.talk to be the same than
cat.talk and Cat to be a prototype just as cat (so Cat must
increase the animal counter and its __init__ method has to
be called at definition time). It is enough to change a
couple of lines in the prototype module:
import sys
from types import FunctionType
from inspect import isfunction
class methodwrapper(object):
def __init__(self,func,cls):
self.__func__ = func
self.__cls__ = cls
def __get__(self,none,cls):
globs=sys.modules[cls.__module__].__dict__.copy()
globs["self"] = globs[cls.__name__] = cls
globs["super"] = super(self.__cls__,cls)
return FunctionType(
self.__func__.func_code,
globs,
self.__func__.func_name,
self.__func__.func_defaults,
self.__func__.func_closure)
class _Prototype(type):
def __init__(cls,name,bases,dic):
for k,v in dic.iteritems():
if isfunction(v):
setattr(cls,k,methodwrapper(v,cls))
super(_Prototype,cls).__init__(name,bases,dic)
cls.__init__()
def __call__(cls,*args,**kw):
newcls = type("Prototype:%s" % cls.__name__,(cls,),
{"__module__": cls.__module__})
newcls.__init__(*args,**kw)
return newcls
class Prototype(object):
__metaclass__=_Prototype
def __init__(*args,**kw):
pass
### END
Here is an example of usage:
from prototype import Prototype
class Animal(Prototype):
numAnimals = 0
home = "Earth"
def __init__():
Animal.numAnimals += 1
def show():
print "Animals:", self.numAnimals
class Feline(Animal):
genus="Feline"
def __init__(name="unknown",sound=""):
super.__init__()
self.name=name
self.sound=sound
def talk():
print "%s talking: %s!" % (self.genus,self.sound)
class Cat(Feline): # created here
numCats = 0
def __init__ ( n = "unknown", s = "Meow" ):
super.__init__(n,s)
Cat.numCats += 1
def show():
super.show()
print " Cats:", self.numCats
def talk():
print "My name is", self.name
print "I am a %s from %s" % (self.genus, self.home)
super.talk()
Cat.talk()
cat = Cat("Garfield")
cat.talk()
More information about the Python-list
mailing list