[Tutor] Re: adding type methods?

Abel Daniel abli at freemail.hu
Thu Oct 23 03:05:13 EDT 2003


Thomi Richards writes:

> I'm just wondering whether it's possible to add methods to a python built in 
> type. for example:

> Is there an easy way to add more functions to these built in types, without 
> having to compile python from source?
>
> This is simply a random thought, without any practical application intended 
> for it (so feel free to ignore)...

Well, in newer pythons (it think after 2.3, with the introduction of
new-style classes) you can subclass any built-in type (in older ones
this wasn't possible, you had to use UserDict, UserList & UserString
modules).

Example:

Python 2.3.1 (#2, Sep 24 2003, 11:39:14) 
[GCC 3.3.2 20030908 (Debian prerelease)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> class newstring(str):
...  def moo(self):
...   print 'moo'
... 
>>> s=newstring('foobar')
>>> s
'foobar'
>>> s.moo()
moo
>>> type(s)
<class '__main__.newstring'>
>>> dir(s)
['__add__', '__class__', '__contains__', '__delattr__', '__dict__',
'__doc__', '__eq__', '__ge__', '__getattribute__', '__getitem__',
'__getnewargs__', '__getslice__', '__gt__', '__hash__', '__init__',
'__le__', '__len__', '__lt__', '__mod__', '__module__', '__mul__',
'__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__',
'__rmod__', '__rmul__', '__setattr__', '__str__', 'capitalize',
'center', 'count', 'decode', 'encode', 'endswith', 'expandtabs',
'find', 'index', 'isalnum', 'isalpha', 'isdigit', 'islower',
'isspace', 'istitle', 'isupper', 'join', 'ljust', 'lower', 'lstrip',
'moo', 'replace', 'rfind', 'rindex', 'rjust', 'rstrip', 'split',
'splitlines', 'startswith', 'strip', 'swapcase', 'title', 'translate',
'upper', 'zfill']
>>> 

Now, this isn't what you asked, because the above example doesn't add
methods to and existing type, it creates a new type. (See the result
of type(s).) I think adding to a built-in type isn't possible:

Trying to add to our class:
>>> def foo(self):
...  print 'foo'
... 
>>> newstring.foo = foo
>>> s.foo()
foo

Trying to add to built-in:
>>> str.foo = foo
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
TypeError: can't set attributes of built-in/extension type 'str'

So I guess you can do that only by writing C code. However, the
difference shouldn't matter. Typechecking isn't good python style. You
should be checking for interfaces not for types. So our newstring
class should be usable everywhere. (It won't be if somebody checks for
types with isinstance() or such, but such code could be considered
broken for not being pythonic.)

-- 
Abel Daniel



More information about the Tutor mailing list