Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Python > Q: Meta-class usage

Reply
Thread Tools

Q: Meta-class usage

 
 
daishi
Guest
Posts: n/a
 
      12-12-2003
Hi,

I am wondering if someone could help me understand some of the
details of using metaclasses.

I am trying to use metaclasses to auto-generate some attributes
and methods in a class definition. I am attaching a simplified
example of the kind of code I am considering below, and I have
the following questions:

1. Is the code in NamedType.__new__ the "right" way to have a
class which has NamedType as its metaclass inherit from
NamedClass? Are the semantics different from if the class with
NamedType as its metaclass explicitly listed NamedClass as a
superclass in the standard way?
2. Is the try/except clause in NameType.__init__ the "right"
way to prevent KeyErrors for subclasses of classes with
NamedType as its metaclass?

Thanks in advance,
d

---
class NamedClass(object):
def __init__(self, name):
self.name = name

class NamedType(type):
def __new__(mcl, name, bases, dictionary):
bases = tuple(list(bases)+[NamedClass])
return super(NamedType, mcl).__new__(mcl, name, bases, dictionary)
def __init__(cls, name, bases, dictionary):
try:
name = dictionary['NAME']
except KeyError:
return
def is_a(self):
return self.name == name
setattr(cls, 'is_a_'+name, is_a)
def init(self):
super(cls, self).__init__(name)
setattr(cls, '__init__', init)

class PrintNamedType(NamedType):
def __init__(cls, name, bases, dictionary):
super(PrintNamedType, cls).__init__(name, bases, dictionary)
def print_name(self):
print self.name
setattr(cls, 'print_name', print_name)

class NamedFoo:
__metaclass__ = NamedType
NAME = 'foo'

class SubNamedFoo(NamedFoo):
pass

class NamedBar:
__metaclass__ = PrintNamedType
NAME = 'bar'
 
Reply With Quote
 
 
 
 
Michael Hudson
Guest
Posts: n/a
 
      12-12-2003
http://www.velocityreviews.com/forums/(E-Mail Removed) (daishi) writes:

> Hi,
>
> I am wondering if someone could help me understand some of the
> details of using metaclasses.
>
> I am trying to use metaclasses to auto-generate some attributes
> and methods in a class definition. I am attaching a simplified
> example of the kind of code I am considering below, and I have
> the following questions:
>
> 1. Is the code in NamedType.__new__ the "right" way to have a
> class which has NamedType as its metaclass inherit from
> NamedClass?


Apart from the fact that tuple(list(bases)+[NamedClass]) is a strange
way of spelling bases + (NamedClass,), yes.

> Are the semantics different from if the class with NamedType as its
> metaclass explicitly listed NamedClass as a superclass in the
> standard way?


Well, potentially, depending on where in the bases list you put
NamedClass. In general, it might be wise to not add NamedClass to the
bases list unless you need to (to avoid MRO calculation errors).

> 2. Is the try/except clause in NameType.__init__ the "right" way to
> prevent KeyErrors for subclasses of classes with NamedType as its
> metaclass?


I'd say so, but I'm not totally sure what you're trying to achieve...

Cheers,
mwh

--
The Internet is full. Go away.
-- http://www.disobey.com/devilshat/ds011101.htm
 
Reply With Quote
 
 
 
 
daishi
Guest
Posts: n/a
 
      12-13-2003
Hi Michael,

Thanks for the response. Some followup inline.

Michael Hudson <(E-Mail Removed)> wrote in message news:<(E-Mail Removed)>...
> (E-Mail Removed) (daishi) writes:
>
> > Hi,
> >
> > I am wondering if someone could help me understand some of the
> > details of using metaclasses.
> >
> > I am trying to use metaclasses to auto-generate some attributes
> > and methods in a class definition. I am attaching a simplified
> > example of the kind of code I am considering below, and I have
> > the following questions:
> >
> > 1. Is the code in NamedType.__new__ the "right" way to have a
> > class which has NamedType as its metaclass inherit from
> > NamedClass?

>
> Apart from the fact that tuple(list(bases)+[NamedClass]) is a strange
> way of spelling bases + (NamedClass,), yes.


Thanks; I had forgotten about being able to do that w/ tuples.

>
> > Are the semantics different from if the class with NamedType as its
> > metaclass explicitly listed NamedClass as a superclass in the
> > standard way?

>
> Well, potentially, depending on where in the bases list you put
> NamedClass. In general, it might be wise to not add NamedClass to the
> bases list unless you need to (to avoid MRO calculation errors).


I was/am having some difficulties understanding what happens here.
E.g., in the example code that I gave if I make the class definition
of NamedFoo to have an explicit superclass:

class NamedFoo(object):

I obtain the error:

Traceback (most recent call last):
File "<stdin>", line 1, in ?
File "meta2.py", line 28, in ?
class NamedFoo(object):
File "meta2.py", line 8, in __new__
return super(NamedType, mcl).__new__(mcl, name, bases, dictionary)
TypeError: Cannot create a consistent method resolution
order (MRO) for bases object, NamedClass

If I add NamedClass to the beginning by doing:

bases = (NamedClass,) + bases

(instead of appending to the end of bases),

I obtain the error:

Traceback (most recent call last):
File "<stdin>", line 1, in ?
File "meta2.py", line 32, in ?
class SubNamedFoo(NamedFoo):
File "meta2.py", line 8, in __new__
return super(NamedType, mcl).__new__(mcl, name, bases, dictionary)
TypeError: Cannot create a consistent method resolution
order (MRO) for bases NamedFoo, NamedClass

(Note that the error is now for class SubNamedFoo instead of
NamedFoo.)

Now based on http://www.python.org/2.3/mro.html I believe this has to
do with the fact that in the first case of NamedFoo we have
merge([object], [NamedClass, object], [object, NamedClass])
(as opposed to
merge([NamedClass, object], [object], [NamedClass, object])
when the modification to bases is changed)

And the SubNamedFoo error arises because of
merge([NamedClass, object], [NamedFoo, NamedClass, object],
[NamedClass, NamedFoo, object])

Is this correct?
(I just want to make sure that I am understanding what's going on
correctly.)

> > 2. Is the try/except clause in NameType.__init__ the "right" way to
> > prevent KeyErrors for subclasses of classes with NamedType as its
> > metaclass?

>
> I'd say so, but I'm not totally sure what you're trying to achieve...


The basic idea of what I'm trying to do is (I think) fairly simple.
I have several fairly similar class definitions that I want, and I
was hoping to use metaclasses to make their definition more compact.
(As comparison, I would use a #define in C or a defmacro in Lisp).
I would like to use these classes once defined as if they were
regularly defined classes, included subclassing. My initial attempt
at subclassing with subclass class SubNamedFoo(NamedFoo) failed
because of the fact that since the metaclass of SubNamedFoo inherits
from NamedFoo and hence becomes NamedType, and the NamedType.__init__
is executed for SubNamedFoo also, which I didn't want - I would like
SubNamedFoo to be oblivious of the fact that NamedFoo was defined
using a customized metaclass. I was wondering what the ideal way to
achieve this might be.

> Cheers,
> mwh


Thanks again,
d
 
Reply With Quote
 
Michele Simionato
Guest
Posts: n/a
 
      12-13-2003
(E-Mail Removed) (daishi) wrote in message news:<(E-Mail Removed). com>...
> Now based on http://www.python.org/2.3/mro.html I believe this has to
> do with the fact that in the first case of NamedFoo we have
> merge([object], [NamedClass, object], [object, NamedClass])
> (as opposed to
> merge([NamedClass, object], [object], [NamedClass, object])
> when the modification to bases is changed)
>
> And the SubNamedFoo error arises because of
> merge([NamedClass, object], [NamedFoo, NamedClass, object],
> [NamedClass, NamedFoo, object])
>
> Is this correct?
> (I just want to make sure that I am understanding what's going on
> correctly.)


Correct. More specific classes should go first to avoid confusion
about the precedence order.

> The basic idea of what I'm trying to do is (I think) fairly simple.
> I have several fairly similar class definitions that I want, and I
> was hoping to use metaclasses to make their definition more compact.
> (As comparison, I would use a #define in C or a defmacro in Lisp).
> I would like to use these classes once defined as if they were
> regularly defined classes, included subclassing. My initial attempt
> at subclassing with subclass class SubNamedFoo(NamedFoo) failed
> because of the fact that since the metaclass of SubNamedFoo inherits
> from NamedFoo and hence becomes NamedType, and the NamedType.__init__
> is executed for SubNamedFoo also, which I didn't want - I would like
> SubNamedFoo to be oblivious of the fact that NamedFoo was defined
> using a customized metaclass. I was wondering what the ideal way to
> achieve this might be.
>


Maybe a simple function acting as a class factory? Sometimes the
simplest solutions are the best solutions. So, unless you anticipate
the need to use inheritance of metaclasses, why don't you use a simple
function return a class (created with type(name,bases,dic), the basic
metaclass) ?

Michele
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
What is the difference between Memory Usage and Heap Usage in my JVMMetrics ? Krist Java 8 02-10-2010 12:44 AM
retrieving CPU Usage and Memory Usage information in JAVA hvt Java 0 03-13-2007 01:09 PM
retrieving CPU Usage and Memory Usage information in JAVA hvt Java 0 03-13-2007 01:07 PM
Webchecker Usage - a problem with local usage Colin J. Williams Python 1 02-26-2004 12:28 AM
Need help on memory usage VS PF usage metfan Java 2 10-21-2003 01:58 PM



Advertisments