Programmatically defining a class: type vs types.new_class

Besides the ability of types.new_class define keyword arguments when creating a class. Are there any significant differences between the two approaches?

 import types First = type('First',(object,),{'asd':99}) k = First() Second = types.new_class('Second',(object,),{},lambda x:x) x = Second() 
+6
source share
2 answers

I understand that this is late, and therefore, you probably already answered this yourself.

First, it seems like you misunderstood the argument kwds types.new_class ; these are class keyword arguments like

 class MyMeta(type): def __new__(metacls, name, bases, attrs, **config): print(config) return super().__new__(metacls, name, bases, attrs) def __init__(cls, name, bases, attrs, **config): super().__init__(name, bases, attrs) class SomeCls(metaclass=MyMeta, debug=True): pass >> {'debug': True} 

similar (no print)

 SomeCls = types.new_class("SomeCls", (), {'debug':True}) 

These meta arguments are useful when setting up metaclasses.

I'm not sure why new_class was designed to accept the called vs an dict directly, but I suspect that it should have avoided the implicit common state between the "new" classes that did not inherit from each other.

0
source

Are there any major differences between the two approaches?

Yes. The answer includes a concept called metaclasses .

[Metaclasses] is a deeper magic than 99% of users should ever worry about. If you are interested in whether you need them, you do not need it (people who really need them know for sure that they need them, and do not need to explain why). Pe Tim Peters, author of Zen of Python ( source )

If you think that you are in these 99%, then do not read further, do not hesitate to just use type . This is as good as types.new_class , except in the rare situation when you use metaclasses.

If you want to learn more about metaclasses, I suggest you take a look at some of the high-quality answers published on the topicWhat are metaclasses in Python? ”. (I recommend it .)

Once you understand what a metaclass is, the answer becomes obvious. Since type is a specific metaclass, it will only work if you want to create classes that use it as their metaclass.

However, if you want to use a non-default metaclass

 class MySimpleMeta(type): pass 

and the static class will not do

 class MyStaticClass(object, metaclass=MySimpleMeta): pass 

then you can use types.new_class

 import types MyStaticClass = types.new_class("MyStaticClass", (object,), {"metaclass": MyMeta}, lambda ns: ns) # this is equivalent to the above class. 

(In short, the reason it requires a called (e.g. lambda ns: ns ) instead of a dictionary is because metaclasses are allowed to take care of the order in which the attributes are defined. )

0
source

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


All Articles