0

consider the following code:

def print_name(*args, **kwargs):

    cls = type(*args, **kwargs)
    print "hello " + cls.name
    return type.__new__( *args, **kwargs)

class B(object):
    __metaclass__ = print_name
    name = 'animal'

class C(B):
    name = "zebra"

class D(B):
    name = "pig"

What i'm trying to achieve is have the function print_name be called on B sub classes(C and D) and make it print the static attribute name. So the desired output should look like this -

animal
zebra
pig

Thank you very much!

1 Answer 1

2

In your print_name() function, you should replace this:

return type.__new__( *args, **kwargs)

with this:

return cls

This way you'll get rid of the TypeError you're seeing.

The error was occurring because the first argument to __new__ must be a type object. The correct invocation for __new__ is: type.__new__(type, *args, **kwargs), but in your case there's really no need to create the class twice.

Now, even with this fix, you won't see 'zebra' and 'pig' in the output, as you're generating your class B directly from type, so that your metaclass information is lost.

You should consider something like this:

class print_name(type):

    def __new__(mcls, *args, **kwargs):
        cls = super(print_name, mcls).__new__(mcls, *args, **kwargs)
        print "hello " + cls.name
        return cls

This way, B and all its subclasses will be of type print_name, and your code will be correctly executed every time a subclass is created.

(As a side note, metaclasses can make it impossible to use multiple inheritance, so think carefully about whether you really need them or not.)

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

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.