Difference between declaring a class with class vs

2019-06-06 15:23发布

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

1条回答
地球回转人心会变
2楼-- · 2019-06-06 15:33

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.

查看更多
登录 后发表回答