According to this tutorial (see the paragraph "Simple metaclass use"), There is a difference between the two declarations:
>>> MyClass = type('MyClass', (), {})
>>> MyClass
<class '__main__.MyClass'>
and
>>> class Meta(type):
... pass
Concerning a difference, this is what the tutorial says:
The class statement isn't just syntactic sugar, it does some extra things, like setting an adequate __qualname__
and __doc__
properties or calling __prepare__
.
The tutorial is written for python 3, but says that footnotes will be given in the instances where python 2 differs. There are no footnotes to be found in this paragraph
I cannot find other tutorials that say the same thing. As a matter of fact, I can find others saying that they are the same. Under the paragraph "The Darker Side of Type", it says about the two declarations:
We could achieve the exact same effect with the following:
The reason for my question is that I have stumbled over a situation where there seems to be a difference. The class declaration works:
class Customers(Base):
__table__ = ERPTables.Customers
While the type declaration does not work:
type('Customers', (Base, ), {'__table__': ERPTables.Customers})
I have been saving the best for last here, but when I say work, I mean in the context of sqlAlchemy. The class declaration yields a result when used in the code below
query = session.query(BasisOfAutoPayment_DK)
pd.read_sql(query.limit(5).statement, session.bind)
While the type declaration does not work when used in the exact same code.
This being sqlAlchemy there is of course a lot going on, but the same objects have been used in both instances. The same Base object, the same Table declaration, the same engine. I thought that the difference were on that side, but I have tried to control for it, and I know believe that it isn't the case. That is why I am now inquiring about the two declarations.
EDIT: Inpecting the two declarations further I can see some similarities and difference in behaviour.
the similarity:
After doing the class declaration. Calling the Class name will produce:
>>> Customers
__main__.Customers
That is the exact same response as the one you get when doing the type declaration:
>>> type('Customers', (Base, ), {'__table__': ERPTables.Customers})
__main__.Customers
A big difference between the two however is:
After the class declaration, you can call the Customers
name and get the output just shown __main__.Customers
.
After the type declaration however, a call to the Customers
name you get a nameerror:
NameError: name 'Customers' is not defined
Obviously why the two are acting differently in the sqlAlchemy query. No wonder it does not work in the type version, if the object cannot be found
This is great tool. yes, a realy great tool because using "type" you can pass any parameter and it will create that object for you.. let say you can use consol input to pass this parameter or use some sort of networking to call this function on a remote computer.
but with "class" you have to hard code the the class types which might make our programm less dynamic.
so it's a great utility for building dynamic and advanced applications.