meta-class review

Ethan Furman ethan at stoneleaf.us
Wed Oct 6 12:33:51 EDT 2010


Carl Banks wrote:
> On Oct 5, 4:17 pm, Ethan Furman <et... at stoneleaf.us> wrote:
>> class DashInt(int):
>>      __metaclass__ = Perpetuate
>>      def __str__(x):
>>          if x == 0:
>>              return '-'
>>          return int.__str__(x)
> 
> Well, it's definitely overkill for printing a dash instead of a zero,
> but a lot of people have asked how to create a subtype of int (or
> other builtin) that coerces the other operand, and your idea is
> interesting in that you don't have to write boilerplate to override
> all the operations.
> 
> Main drawback is that it's incomplete.  For example, it doesn't coerce
> properties.  int.real returns the real part of the int (i.e., the int
> itself).  A subclass's real attribute should return an instance of the
> subclass, but it won't.

Python 2.5.4 (r254:67916, Dec 23 2008, 15:10:54) [MSC v.1310 32 bit 
(Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
 >>> a = int()
 >>> a
0
 >>> a.real
Traceback (most recent call last):
   File "<stdin>", line 1, in <module>
AttributeError: 'int' object has no attribute 'real'
 >>> int.real()
Traceback (most recent call last):
   File "<stdin>", line 1, in <module>
AttributeError: type object 'int' has no attribute 'real'

What am I missing here?

> Another example is float.__divmod__, which
> returns a tuple.  Your coercive type would fail to convert the items
> of that tuple.  

Good point -- I'll get that included.

> A metaclass like this I think would be possible, with
> the understanding that it can never be foolproof, but it needs more
> work.
> 
> Pointers:
> Defining __init__ isn't necessary for this metaclass.
> 
> The "len(cls_bases) > 1" test can be thwarted if the base type
> multiply inherits from other types itself.  The best thing to do is
> handle the case of arbitrary type hierarchies, but if you don't want
> to do that then the right way to catch it is to create the subtype
> then check that the __mro__ is (type, base_type, object).

Thanks for the tips, Carl.

What I had wanted was to be able to specify which type(s) to look for in 
cases of multiple inheritance, but I'm not sure how to pass parameters 
to the metaclass in python2...

Can anybody shed some light on that?

Thanks!

~Ethan~



More information about the Python-list mailing list