type(obj) 和 obj.__class__ 之间的区别
type(obj)
和 obj.__class__
有什么区别? 是否有可能 type(obj) 不是 obj.__class__
?
我想编写一个对所提供的对象通用的函数,使用与另一个参数相同类型的默认值 1。 下面的#1 或#2 哪种变体会做正确的事情?
def f(a, b=None):
if b is None:
b = type(a)(1) # #1
b = a.__class__(1) # #2
What is the difference between type(obj)
and obj.__class__
? Is there ever a possibility of type(obj) is not obj.__class__
?
I want to write a function that works generically on the supplied objects, using a default value of 1 in the same type as another parameter. Which variation, #1 or #2 below, is going to do the right thing?
def f(a, b=None):
if b is None:
b = type(a)(1) # #1
b = a.__class__(1) # #2
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
这是一个老问题,但似乎没有一个答案提到这一点。 在一般情况下,新样式类可能有不同的
type(instance)
和instance.__class__
值: :
原因是
ClassB
覆盖了__class__
描述符,但对象中的内部类型字段并未更改。type(instance)
直接从该类型字段读取,因此它返回正确的值,而instance.__class__
指的是新的描述符替换 Python 提供的原始描述符,这读取内部类型字段。 它不读取该内部类型字段,而是返回一个硬编码值。This is an old question, but none of the answers seems to mention that. in the general case, it IS possible for a new-style class to have different values for
type(instance)
andinstance.__class__
:Output:
The reason is that
ClassB
is overriding the__class__
descriptor, however the internal type field in the object is not changed.type(instance)
reads directly from that type field, so it returns the correct value, whereasinstance.__class__
refers to the new descriptor replacing the original descriptor provided by Python, which reads the internal type field. Instead of reading that internal type field, it returns a hardcoded value.旧式类是问题所在,叹息:
在 Python 3 中不是问题,因为现在所有类都是新式的;-)。
在Python 2中,只有当一个类继承自另一个新式类(包括
object
和各种内置类型,例如dict
、>list
、set
、...) 或隐式或显式将__metaclass__
设置为type
。Old-style classes are the problem, sigh:
Not a problem in Python 3 since all classes are new-style now;-).
In Python 2, a class is new-style only if it inherits from another new-style class (including
object
and the various built-in types such asdict
,list
,set
, ...) or implicitly or explicitly sets__metaclass__
totype
.对于 Python 2 中的旧样式类,
type(obj)
和type.__class__
的行为不同:对此进行了解释 文档中:
type(obj)
andtype.__class__
do not behave the same for old style classes in Python 2:This is explained in the documentation:
代理对象(使用弱引用)有一个有趣的边缘情况:
There's an interesting edge case with proxy objects (that use weak references):
仅供参考 - Django 就是这样做的。
作为一个认知能力有限的人,只是想弄清楚正在发生什么才能完成工作……这是令人沮丧的。
FYI - Django does this.
As someone with finite cognitive capacity who's just trying to figure out what's going in order to get work done... it's frustrating.
这将使您更好地理解差异:
概括:
classA.one、self.class.one 和 type(obj).one 是相同的。
self.one 和 obj.one 是相同的,并且它们在每个实例中都是不同的。
This will give you a more understanding of the differences:
Summary:
classA.one, self.class.one and type(obj).one are the same.
self.one and obj.one are the same and they are distinct per instance.