3

I'd like to modify all classes in Python. For example str and int and others like Person(object).

I'd like to add an attribute to them and to change the way its methods works.

Which is the best approach for this? Metaclasses?

3
  • Implementing a taint mode for Python. Commented Jan 29, 2010 at 21:50
  • 2
    You would also need to be able to re-implement all the operators in the language as well. I don't think you're going to be able to do what you want. Commented Jan 29, 2010 at 22:19
  • Since Python doesn't have the magic assignments of stdin to variables and such that Perl has, I'm not sure why you would need one. Just verify/escape all input. Am I missing something weird in that? Commented Jan 29, 2010 at 22:21

4 Answers 4

3

While you can do this for classes defined in python code (it will not work for builtin ones) by reassigning their attributes please do not actually do so. Just subclass and use the subclass, or write functions that take an instance of the class as argument instead of adding your own methods. Doing what you have to mind leads to awkward, fragile code, especially if you end up using multiple libraries simultaneously that try to do this to the same classes.

Is there an actual problem you're trying to solve this way?

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

Comments

2

Built-in classes can't be modified, but you can "hide" a built-in class (or any other of course) by one of the same name.

For example, suppose that the change is to add to a bunch of classes a new attribute "foobar" whose initial value is 23, and to every instance of those classes a new attribute "murf" whose initial value is 45. Here's one way:

def changedclass(cls):
  def __init__(self, *a, **k):
    cls.__init__(self, *a, **k)
    self.murf = 45
  return type(cls.__name__, (cls,), {'foobar': 23, '__init__': __init__})

def changemany(changed, classes_by_module):
  for module, classnames in classes_by_module.iteritems():
    for name in classnames:
      cls = getattr(module, name)
      subcls = changed(cls)
      setattr(module, name, subcls)

import __builtin__
import mymod
changemany(changedclass, {__builtin__: ('int', 'str'), mymod: ('Person',)})

Note that bare literals like 'ciao' and 23 will still belong to the real classes -- there's no way to change that; you'll need to use str('ciao') and int(23) to use the "fake" classes.

1 Comment

How could you overload the __add__ method for the changed class?
1

You can't edit the class directly like you might with javascript's prototype attribute, it's better if you subclass them. This let's you add the functionality you want and not force it to be used everywhere.

3 Comments

Ok, how can I do that programmaticly? I'd like to apply this modification to a lot of classes. I don't want to extend all of them by hand.
You might want to use a class decorator which returns a modified version for the class. Then you only have to add "@yourdecorator" at the top of each class that should be modified.
decorator is just a class, programmatically you would use a function that returns your function.... str = decoratorTest(str) the same way you can apply @property as we know and function property(str) that returns decorated function, in this case it is decorated as property
0

subclass:


class int(int):
  def foo(self):
   print "foo"

int(2).foo()

Comments

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.