Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Python > Why are so many built-in types inheritable?

Reply
Thread Tools

Why are so many built-in types inheritable?

 
 
Fabiano Sidler
Guest
Posts: n/a
 
      03-18-2006
Hi folks!

For debugging purposes I tried this:

--- snip ---
def foo(): pass
function = type(foo)

class PrintingFunction(function):
def __init__(self, func):
self.func = func
def __call__(self, *args, **kwargs):
print args, kwargs
return function.__call__(self, args, kwargs)

class DebugMeta(type):
def __new__(self, name, bases, dict):
for name in dict:
if type(dict[name]) is function:
dict[name] = PrintingFunction(dict[name])

--- snap ---

Now I tought I were able to let all maethod of classes with DebugMeta as
metaclass print out their arguments. But I got the following sad error:

TypeError: Error when calling the metaclass bases
type 'function' is not an acceptable base type

That's awful, isn't it?
What could I do to get the above code working? (No, I disliked to re-
implement <type 'function'> without this unpleasant behaviour in Python.)

Greetings,
F. Sidler

 
Reply With Quote
 
 
 
 
Fabiano Sidler
Guest
Posts: n/a
 
      03-25-2006
Hello? Or, is there any obvious reason for this behaviour I don't see?

 
Reply With Quote
 
 
 
 
Kent Johnson
Guest
Posts: n/a
 
      03-25-2006
Fabiano Sidler wrote:
> Hi folks!
>
> For debugging purposes I tried this:
>
> --- snip ---
> def foo(): pass
> function = type(foo)
>
> class PrintingFunction(function):
> def __init__(self, func):
> self.func = func
> def __call__(self, *args, **kwargs):
> print args, kwargs
> return function.__call__(self, args, kwargs)
>
> class DebugMeta(type):
> def __new__(self, name, bases, dict):
> for name in dict:
> if type(dict[name]) is function:
> dict[name] = PrintingFunction(dict[name])
>
> --- snap ---
>
> Now I tought I were able to let all maethod of classes with DebugMeta as
> metaclass print out their arguments. But I got the following sad error:
>
> TypeError: Error when calling the metaclass bases
> type 'function' is not an acceptable base type
>
> That's awful, isn't it?
> What could I do to get the above code working? (No, I disliked to re-
> implement <type 'function'> without this unpleasant behaviour in Python.)


You could do this with a simple decorator:
http://wiki.python.org/moin/PythonDe...fec0ff4b3653f4

or I think your class PrintingFunction would work as
class PrintingFunction(object):
def __init__(self, func):
self.func = func
def __call__(self, *args, **kwargs):
print args, kwargs
return self.func(*args, **kwargs)

Kent
 
Reply With Quote
 
Fabiano Sidler
Guest
Posts: n/a
 
      03-25-2006
Kent Johnson <(E-Mail Removed)> wrote:
> You could do this with a simple decorator:
> http://wiki.python.org/moin/PythonDe...fec0ff4b3653f4
>
> or I think your class PrintingFunction would work as
> class PrintingFunction(object):
> def __init__(self, func):
> self.func = func
> def __call__(self, *args, **kwargs):
> print args, kwargs
> return self.func(*args, **kwargs)


The problem with this is that the func_code attribute would contain
the code of PrintingFunction instead of func. What I wanted to do, is
to keep the original behaviour, i.e. set the variable __metaclass__ to
DebugMeta and so get debug output, without changing a function and
getting the original function's code object by the func_code
attribute, not PrintigFunction's one. That's why I *must* inherit from
<type 'function'>.

Greetings,
F. Sidler
 
Reply With Quote
 
Ziga Seilnacht
Guest
Posts: n/a
 
      03-25-2006
Fabiano Sidler wrote:

[snipped]

> The problem with this is that the func_code attribute would contain
> the code of PrintingFunction instead of func. What I wanted to do, is
> to keep the original behaviour, i.e. set the variable __metaclass__ to
> DebugMeta and so get debug output, without changing a function and
> getting the original function's code object by the func_code
> attribute, not PrintigFunction's one. That's why I *must* inherit from
> <type 'function'>.


No, you don't have to:

>>> import new
>>> import types
>>> class DebugFunction(object):

.... def __init__(self, func):
.... object.__setattr__(self, 'func', func)
.... def __get__(self, obj, objtype):
.... return new.instancemethod(self, obj, objtype)
.... def __call__(self, *args, **namedargs):
.... print args, namedargs
.... func = object.__getattribute__(self, 'func')
.... return func(*args, **namedargs)
.... def __getattribute__(self, name):
.... func = object.__getattribute__(self, 'func')
.... return getattr(func, name)
.... def __setattr__(self, name, value):
.... func = object.__getattribute__(self, 'func')
.... setattr(func, name, value)
.... def __delattr__(self, name):
.... func = object.__getattribute__(self, 'func')
.... delattr(func, name)
....
>>> class DebugMeta(type):

.... def __new__(meta, name, bases, dict):
.... for name, obj in dict.iteritems():
.... if isinstance(obj, types.FunctionType):
.... dict[name] = DebugFunction(obj)
.... return type.__new__(meta, name, bases, dict)
....
>>> class Example(object):

.... __metaclass__ = DebugMeta
.... def spam(self, *args, **namedargs):
.... """Spam spam spam spam. Lovely spam! Wonderful spam!"""
.... pass
....
>>> e = Example()
>>> e.spam('eggs', anwser=42)

(<__main__.spam object at ...>, 'eggs') {'anwser': 42}
>>> e.spam.__doc__

'Spam spam spam spam. Lovely spam! Wonderful spam!'
>>> e.spam.im_func.func_code

<code object spam at ..., file "<stdin>", line 3>


> Greetings,
> F. Sidler


Ziga

 
Reply With Quote
 
Fabiano Sidler
Guest
Posts: n/a
 
      03-26-2006
25 Mar 2006 13:58:17 -0800, Ziga Seilnacht <(E-Mail Removed)>:
> No, you don't have to:


Okay, but I'd prefer!

> [a lot of python code]


That's what I wanted to avoid. Additionally, the possibility to do it
this way doesn't make it reasonable that <type 'function'> is
inheritable. Are there any reasons for that?

Greetings,
F.Sidler
 
Reply With Quote
 
Fabiano Sidler
Guest
Posts: n/a
 
      03-28-2006
I really wanted to learn the reason for this, nothing else!

Greetings,
F. Sidler
 
Reply With Quote
 
Georg Brandl
Guest
Posts: n/a
 
      03-28-2006
Fabiano Sidler wrote:
> I really wanted to learn the reason for this, nothing else!


I suspect performance reasons. Can't give you details but function
is used so often that it deserves special treatment.

Georg
 
Reply With Quote
 
Antoon Pardon
Guest
Posts: n/a
 
      03-30-2006
Op 2006-03-28, Georg Brandl schreef <(E-Mail Removed)>:
> Fabiano Sidler wrote:
>> I really wanted to learn the reason for this, nothing else!

>
> I suspect performance reasons. Can't give you details but function
> is used so often that it deserves special treatment.


I would find this a bit odd. I think integers, tuples and lists
are used just as often if not more and they aren't treated special.

I for one would gladly treat some performance for the ability
to subclass slices.

class islice(slice):
...

doesn't work


And if I just write

class islice:

def __init__(self, start, stop, step):
self.start = start
self.stop = stop
self.step = step

then the following doesn't work:

lst = range(20)
sl = islice(2,6,None)
lst[sl]


So much for ducktyping.

--
Antoon Pardon
 
Reply With Quote
 
Georg Brandl
Guest
Posts: n/a
 
      03-30-2006
Antoon Pardon wrote:
> Op 2006-03-28, Georg Brandl schreef <(E-Mail Removed)>:
>> Fabiano Sidler wrote:
>>> I really wanted to learn the reason for this, nothing else!

>>
>> I suspect performance reasons. Can't give you details but function
>> is used so often that it deserves special treatment.

>
> I would find this a bit odd. I think integers, tuples and lists
> are used just as often if not more and they aren't treated special.


Well, for integers, tuples and lists you can at least give useful
use cases for subclassing.

I now looked in the code, and the ability to subclass is given by a
flag in the type object. This is there in list or int, but not in function.

A little performance is saved by the fact that PyFunction_Check, which
verifies that an object is indeed a function, doesn't have to check for
subtypes.

So, if you want to make functions or slices subclassable, ask on python-dev!

Georg
 
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
why why why why why Mr. SweatyFinger ASP .Net 4 12-21-2006 01:15 PM
findcontrol("PlaceHolderPrice") why why why why why why why why why why why Mr. SweatyFinger ASP .Net 2 12-02-2006 03:46 PM
Can XSD simple types be derived from complex types? Soren Kuula XML 2 12-01-2005 07:51 PM
Where are ref types that are members of value types stored? Sathyaish ASP .Net 2 05-22-2005 07:32 PM
A simple way to track available memory in C/C++ and why is there so many different types of it? Office Drone C++ 7 07-27-2004 09:01 PM



Advertisments