Are classless methods in Python useful for anything?

I just noticed that you can do this in Python:

def f(self):
    print self.name

class A:
    z=f
    name="A"

class B:
    z=f
    name = "B"

print a.z()

>>> A

In other words, f() behaves like a method that is not defined on any class, but can be attached to one. And of course it will produce a runtime error if it expects methods or fields on the object that it is attached to, which don't exist.

My question: is this useful? Does it serve a purpose? Are there situations where it solves a problem? Maybe it's a way of defining interfaces?

Answers


Yes, it is useful and it does serve a purpose, but it is also quite rare to have to do this. If you think you need to patch classes after they've been defined you should always stop and consider whether it really is the best way.

One situation is monkey-patching. I've done this in a large Plone system where some methods needed minor tweaks but there just wasn't any easy way to override the behaviour normally. In that situation where you have a complex library it provides an easy way to inject new or modified behaviour without having to change the original library.

The other situation that springs to mind is when you want a lot of methods that can be generated automatically. e.g. data driven tests.

def createTest(testcase, somedata, index):
    def test(self):
         "Do something with somedata and assert a result"
    test_name = "test_%d" % index
    setattr(testcase, test_name, test)

for index, somedata in enumerate(somebigtable):
    createTest(MyTestCase, somedata, index)

when MyTestCase is a unittest.TestCase you could have one test that goes through all of the data but it stops at the first failure and you than have to try to figure out which line of data failed. By dynamically creating the methods all the tests run separately and the test name tells you which one failed (the original of the code above actually built a more meaningful name involving some of the data as well as the index).

You can't do that inside the body of the class because there's no way to either reference the class itself or its dictionary before the definition is complete. You can however do something similar with a metaclass as that lets you modify the class dict before creating the class itself and sometimes that is a cleaner way of doing the same sort of thing.

The other thing to note is that there are situations where this won't work. Some __xxx__ special methods cannot be overridden after the class has been created: the original definition is saved internally somewhere other than the class's __dict__ so any changes you make later may be ignored. Also if working with metaclasses sometimes additional functions won't get whatever treatment the metaclass gives to attributes as part of the class definition.


Need Your Help

PHP money_format

php string locale string-formatting money-format

I'm using on money_format with the first parameter being '%n' to include the dollar sign, and I have the locale set to en_US but it still doesn't include it. Why?

Create an object in memory pointed to by a void pointer

c++ pointers memory-management sizeof memcpy

If I have a void* to some chunk of free memory and I know there is at least sizeof(T) available, is there any way to create an object of type T in that location in memory?