1

I want to use @classmethod, but I don't want to pollute the instance's namespace with it. If I have a class method for_classes_only, how do I keep the instance from getting it?

class MyThing(object):
    def __init__(self, this=None):
        self.this = this

    @classmethod
    def for_classes_only(cls):
        print "I have a class {}".format(cls)


thing = MyThing(this='that')

This is great:

>>> MyThing.for_classes_only()
I have a class <class '__main__.MyThing'>

This is annoying:

>>> thing.for_classes_only
<bound method type.for_classes_only of <class '__main__.MyThing'>>
Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
jkmacc
  • 6,125
  • 3
  • 30
  • 27
  • 5
    *Everything* on a class is accessible on the instance. It doesn't *live* there, it is that Python looks at the class when attributes are not present on the instance itself. Use a function *outside the class* if you don't want instances to see it too. You'll have to pass in the class explicitly of course, as it won't be bound. – Martijn Pieters Dec 18 '14 at 22:18
  • So "class method" just means that the method receives the class, not that the method is restricted to the class. Got it. – jkmacc Dec 18 '14 at 22:30
  • You can't hide it but you could make its behaviour change based on whether or not the class has been instantiated, e.g. by setting a flag in `__init__`. – 101 Dec 18 '14 at 23:07

1 Answers1

2

Try using a metaclass:

class Meta(type):
    # There is *NO* @classmethod decorator here
    def my_class_method(cls):
        print "I have a class {}".format(cls)

class MyThing(object):
    __metaclass__ = Meta
    def __init__(self, this=None):
        self.this = this

This is heavier magic than most people need or want, so only do this if you're really quite sure you need it. Most of the time, a normal @classmethod is good enough.

Community
  • 1
  • 1
Kevin
  • 28,963
  • 9
  • 62
  • 81
  • You're right, this is overkill for an annoyance. But it gets the job done:-) I happen to be working with a metaclass, so this is just fine. Thanks! – jkmacc Dec 19 '14 at 16:42