0

I have the following:

class X(object):
    def __init__(self, *args, **kwargs):
        type(self).label_type = xyzzy(self.__class__.__name__)

class Y(X):
    def __init__(self, *args, **kwargs):
        super(Y, self).__init__(self, *args, **kwargs)

When I create a new instance of Y, a class variable called label_type is created using Y, not X. This is good and works fine.

But it burns me that I have to wait until there's an instance of Y before the class variable is created. How can I set label_type when class Y is compiled, not when it is instantiated?

EDIT - I have numerous subclasses that are derived from X. I want to push as much of the work into X as possible.

1
  • Have either of the answers addressed your issue? If not, could you clarify further? Commented Oct 28, 2015 at 11:12

2 Answers 2

3

You can use a metaclass to do this kind of thing. Here's a trivial example to demonstrate:

class NameLabelMeta(type):

    def __new__(meta, name, bases, dct):
        """Create a new class and label it with its name."""
        cls = super(NameLabelMeta, meta).__new__(meta, name, bases, dct)
        cls.label_type = name  # or xyzzy(name), or whatever
        return cls

In use:

>>> class X(object):
    __metaclass__ = NameLabelMeta  # 2.x syntax


>>> class Y(X):
    pass

>>> Y.label_type
'Y'

Note that Y transparently inherits the metaclass from X, so doesn't need to implement anything at all for the correct behaviour to occur. It's also much more efficient, as it doesn't happen again every time you create a new instance of the class.

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

2 Comments

This looks like it will work, but I need time to understand it.
@TonyEnnis that's fair enough! A metaclass lets you customise creation of classes, in the same way that a class lets you customise creation of instances. See e.g. stackoverflow.com/q/100003/3001761
2

Do you need to set the label_type dynamically? Why not use a "static variable" such as

class X(object):
    LABEL_TYPE = 'X'

class Y(X):
    pass

print Y().LABEL_TYPE # Prints 'X'

2 Comments

I believe the OP would like Y.LABEL_TYPE to be derived from 'Y', not 'X'.
Additional reason added to OP

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.