What is wrong with this simple python metaclass?

Start of retreat

I just found out what metaclasses are in Python. I do not think that the creators of python wanted everyone to use them. I mean, to call something a metaclass, which cannot be a class in most cases, is enough to distract most people from this concept!

Retreat End

On my question. I wrote this simple metaclass to add a default doc string for all classes created in the module. But it does not work:

def metest(cls,name,bases,dict): cls.setattr(cls,'__doc__',"""Default Doc""") return type(cls,(),{}) __metaclass__=metest class test(object): pass print test.__doc__ t=test() print t.__doc__ 

Conclusion:

 None None 

What am I doing wrong?

+6
source share
5 answers

I made your work example:

 def metest(name, bases, dict): print name, bases, dict dict['__doc__'] = """New Doc""" cls = type(name+"_meta", bases, dict) return cls class Test(object): "Old doc" __metaclass__ = metest print Test print Test.__doc__ t = Test() print t.__doc__ 
  • Use metaclass.
  • Correct the signature of the "class creation function". cls will be created by us.
  • For distinction, there is an "old" and a "new" docstring.
+3
source

I am not completely familiar with the global approach you are doing by setting __metaclass__ like this. As far as I know, his is another acting style.

But I will give an example of what I am familiar with:

 class MeTest(type): def __new__(cls,name,bases,dict): dict['__doc__'] = """Default Doc""" return type.__new__(cls,name,bases,dict) class Test(object): __metaclass__ = MeTest 
+4
source

See this answer: Python class metaclass and object base class

Providing a base class of object overrides the module-level metaclass and replaces it with type ( object metaclass).

In addition, your metaclass is faulty and does not work, even if you apply it (by setting __metaclass__ inside the class). It should take only three arguments. Usually you see examples that take four, but this is because the metaclass is usually, guess what, the class, so it takes an additional argument "self" (which is called cls for metaclasses by standard).

+2
source

Perhaps this is what you want. Inheriting from object will result in a type metaclass, so you cannot do this if you want to use a global metaclass

 def metest(name, bases, dct): dct['__doc__'] = """Default Doc""" return type(name, bases, dct) __metaclass__=metest class test: pass print test.__doc__ t=test() print t.__doc__ 
+1
source

The module level metaclass is overridden as described above by BrenBarn. To fix this, try copying it to return cls instead of setting it as an instance of the class.

+1
source

Source: https://habr.com/ru/post/919296/


All Articles