1

I'm trying to mimic methods.grep from Ruby which simply returns a list of available methods for any object (class or instance) called upon, filtered by regexp pattern passed to grep. Very handy for investigating objects in an interactive prompt.

def methods_grep(self, pattern):
    """ returns list of object's method by a regexp pattern """
    from re import search
    return [meth_name for meth_name in dir(self) \
            if search(pattern, meth_name)]

Because of Python's limitation not quite clear to me it unfortunately can't be simply inserted in the object class ancestor:

object.mgrep = classmethod(methods_grep)
# TypeError: can't set attributes of built-in/extension type 'object'

Is there some workaround how to inject all classes or do I have to stick with a global function like dir ?

4
  • You can list all the methods an object has using dir(), e.g. dir(some_object) (edit: ok I see you already know that ;) Commented Jun 11, 2014 at 13:02
  • @James I'm aware of that, it's used in the example methods_grep function. I need a function available on all objects which returns all available methods filtered by the pattern given as argument. Commented Jun 11, 2014 at 13:05
  • @James For example str.mgrep('split') would return ['_formatter_field_name_split', 'rsplit', 'split', 'splitlines']. Commented Jun 11, 2014 at 13:06
  • You might fake it using the mock module, although it might be dicey setting up a Mock that delegates every thing to the original object type in addition to handling the mgrep method as well. Commented Jun 11, 2014 at 13:17

2 Answers 2

4

There is a module called forbiddenfruit that enables you to patch built-in objects. It also allows you to reverse the changes. You can find it here https://pypi.python.org/pypi/forbiddenfruit/0.1.1

from forbiddenfruit import curse    
curse(object, "methods_grep", classmethod(methods_grep))

Of course, using this in production code is likely a bad idea.

Sign up to request clarification or add additional context in comments.

3 Comments

Thanks, it looks interesting. What's wrong with that module in production use ? Performance issues ?
Note that this is not a pure Python module. It's a C plugin to Python. This at least makes it less compatible with different Python versions. +1 though since it answers the question.
@David I was referring to the general practice of modifying built-in types. For your stated purpose it is probably harmless.
2

There is no workaround AFAIK. I find it quite annoying that you can't alter built-in classes. Personal opinion though.

One way would be to create a base object and force all your objects to inherit from it.

But I don't see the problem to be honest. You can simply use methods_grep(object, pattern), right? You don't have to insert it anywhere.

2 Comments

This is both safer and less error prone to other people using your library.
Thanks. I've presumed I'd need to stick with this and leave it as a global function.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.