Skip to content Skip to sidebar Skip to footer

Weird Inheritance With Metaclasses

I'm experiencing some really weird problems in Python when trying to inherit from a class with a metaclass. I have this: class NotifierMetaclass(type): def __new__(cls, name,

Solution 1:

Okay, I think I figured it out. The correct class is being imported. It just has the wrong name. You should be able to see this if you set attributes on the classes. If you put someJunk = "Notifier" in the Notifier definition and someJunk = "CommentNotifier" in the CommentNotifier definition, then when you import CommentNotifier it will have the right value.

The problem is that in creating your attrs, you exclude all double-underscore attributes, including __module__. When you call the superclass __new__, you pass in your attrs, which does not have a __module__ entry, so Python creates one for you. But since this code is executing inside the file containing the metaclass, the module is incorrectly set to the metaclass's file and not the actual class's file.

I'm not seeing the behavior you observe for the actual name of the class, only for the module. That is, for me the imported class is named metafile.CommentNotifier, where metafile is the file containing the metaclass. It should be named submeta.CommentNotifier, where submeta is the file containing the CommentNotifierClass. I'm not sure why you're seeing it for __name__ as well, but it wouldn't surprise me if some subtle handling of module/name assignment varies across different Python versions.

__notify__ and __notification__ are not Python magic methods. It appears that you're excluding double-underscore methods because you are using double underscores to indicate something for your own purposes. You shouldn't do this. Use some other prefix for your own methods (like _Notifier or something) if you must, then exclude those methods and leave the double-underscore ones alone. Excluding double-underscore methods could cause other problems. In particular, it will cause failure if you ever decide to define a real magic method (e.g., __str__) on a class that uses this metaclass.

(To clarify: you can use methods that begin with double underscores if you want, as private attributes, although this still is probably not a good idea. If you do this, though, you need to make sure you only do your special processing on those attributes, and not ones that begin and end with double underscores, which are Python-internal magic methods. What you shouldn't do is create your own names that begin and end with double underscores, like __notify__.)

Post a Comment for "Weird Inheritance With Metaclasses"