9

I need to be able to set a flag on a class (not on an instance of a class) which is not visible to a subclass. The question is, is it possible, and how would I do it if it is?

To illustrate, I want something like this:

class Master(SomeOtherClass):
    __flag__ = True

class Child(Master):
    pass

... where hasattr(Master, "__flag__") should return True for Master but False for Child. Is this possible? If so, how? I don't want to have to explicitly set __flag__ to false in every child.

My initial thought was to define __metaclass__, but I don't have the luxury of doing that because Master inherits from some other classes and metaclasses I don't control and which are private.

Ultimately I'm wanting to write a decorator so that I can do something like:

@hide_this
class Master(SomeOtherClass): pass

@hide_this
class Child(Master): pass

class GrandChild(Child): pass
...
for cls in (Master, Child, GrandChild)
    if cls.__hidden__:
        # Master, Child
    else:
        # GrandChild
3
  • 1
    You could make it __hidden, then only classes where it was directly defined would have a _ClassName__hidden attribute. Commented Jun 19, 2015 at 18:57
  • Is there a reason you don't want to write cls.__dict__.get('__hidden__'), other than that it's ugly? Commented Jun 19, 2015 at 18:59
  • @jonrsharpe: nope, that solution didn't occur to me. That will work fantastically. Write up an answer so I can accept it if you want. If you don't, I'll add the answer myself for future reference. Thanks! Commented Jun 19, 2015 at 19:47

1 Answer 1

6

You were very close:

class Master(SomeOtherClass):
    __flag = True

class Child(Master):
    pass

Two leading underscores without trailing underscores invokes name mangling, so the attribute will be named _Master__flag. Therefore if you check:

hasattr(cls, '_{}__flag'.format(cls.__name__))

it will only be True for Master, not Child.

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

2 Comments

That's not precisely what I'm looking for -- I don't have an instance of the class, I just have the class. The technique works the same, though.
@BryanOakley yes, it's the same with classes; updated accordingly!

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.