我正在阅读http://blog.thedigitalcatonline.com/blog/2014/09/01/python-3-oop-part-5-metaclasses/#.Vv1T7zG1XGA,其中包含:
因为在Python中一切都是对象,所以一切都是类的实例,甚至是类.好吧,type是实例化的类来获取类.所以请记住:object是每个对象的基础,type是每个类型的类.听起来令人费解?这不是你的错,不用担心.然而,只是为了让你完成整理,这就是Python的基础
>>> type(object)
<class 'type'>
>>> type.__bases__
(<class 'object'>,)
Run Code Online (Sandbox Code Playgroud)
我无法理解这一点,任何人都可以用不同的方式解释这种关系,以使其更清晰吗?
之间的关系type(x)与 的结果基本相同x.__class__:
for obj in (object,type,1,str):
assert type(obj) is obj.__class__
print("type(obj) and obj.__class__ gave the same results in all test cases")
Run Code Online (Sandbox Code Playgroud)
__bases__表示派生类的基础:
class parent:
pass
class child(parent,int):
pass
print(child.__bases__) # prints (<class '__main__.parent'>, <class 'int'>)
Run Code Online (Sandbox Code Playgroud)
但是,如果您询问object和之间的奇怪关系type:
# are `object` and `type` both instances of the `object` class?
>>> isinstance(object, object) and isinstance(type, object)
True
# are they also instances of the `type` class?
>>> isinstance(object, type) and isinstance(type, type)
True
# `type` is a subclass of `object` and not the other way around (this makes sense)
>>> [issubclass(type, object), issubclass(object, type)]
[True, False]
Run Code Online (Sandbox Code Playgroud)
这更像是先有鸡还是先有蛋的问题:哪个先有?
答案是PyObjectC中定义的。
object在 python 解释器可以使用或之前,type它们的底层机制是用 C 定义的,并且在定义后实例检查将被覆盖。(像抽象类一样,参见PEP 3119)
你可以将其视为类似于以下 python 实现:
#this wouldn't be available in python
class superTYPE(type):
def __instancecheck__(cls,inst):
if inst ==TYPE:
return True
else:
return NotImplemented #for this demo
class TYPE(type,metaclass=superTYPE):
def __instancecheck__(cls,inst):
if inst in (OBJECT,TYPE):
return True
else:
return NotImplemented #for this demo
class OBJECT(metaclass=TYPE):
pass
# these all pass
assert isinstance(TYPE,OBJECT)
assert isinstance(OBJECT,TYPE)
assert isinstance(TYPE,TYPE)
assert isinstance(OBJECT,OBJECT)
Run Code Online (Sandbox Code Playgroud)
实际上它可能更好地表示为:
#this isn't available in python
class superTYPE(type):
def __instancecheck__(cls,inst):
if inst in (TYPE,OBJECT):
return True
else:
return NotImplemented #for this demo
class OBJECT(metaclass=superTYPE):
pass
class TYPE(OBJECT):
pass
Run Code Online (Sandbox Code Playgroud)
但如果你想确切地知道它是如何工作的,你需要查看用 C 编写的源代码。
这真的很奇怪,感觉就像乌龟一路向下。事实上,我以前并没有深入研究过这个领域,尽管它听起来很有趣而且很强大。这个解释很令人困惑,该页面上的其余信息也是如此,但我觉得我得到了一些启示。我不确定是否能解释清楚,但我会尝试一下。
我们先来看看海龟:
>>> isinstance(type, object)
True
>>> isinstance(object, type)
True
Run Code Online (Sandbox Code Playgroud)
等等,什么?
object的实例如何type,何时type是 的实例object?感觉就像是在说这样的话:
class Parrot: pass
ex = Parrot()
isinstance(ex, Parrot)
isinstance(Parrot, ex)
Run Code Online (Sandbox Code Playgroud)
应该是True两次。但显然不是。甚至(正如 Tadhg McDonald-Jensen 指出的那样)
>>> isinstance(type, type)
True
Run Code Online (Sandbox Code Playgroud)
这应该向您表明幕后正在发生一些魔法。所以在这一点上,让我们完全忘记Python(我知道,为什么我们会想做这么可怕的事情?)
一般来说,所有计算机程序都是 1 和 0 (更准确地说,它们只是一堆>~2.5v 和~<2.5v 的逻辑门和电子,但 0 和 1 就足够了)。无论您是用汇编语言、实际机器代码、Python、C#、Java、Perl 还是其他语言编写它 - 它们都只是位。
如果您编写一个类定义,那么该类只是位。该类的实例只是更多的位。编程语言、编译器和解释器只是更多的位。
就 Python 而言,解释python器为 Python 程序的各个位赋予了意义。有趣的是,我们通常认为是 Python 的很多内容实际上是用 Python 编写的(尽管其中大部分是 C,对于我们 CPython 人员来说是 C,对于 Jython 来说是 Java 等)。
现在我们来谈谈我们称之为type和 的东西object。正如文章所指出的,它们有点特别。所以,我们知道我们可以创建一个类,然后该类就是一个对象:
>>> class Confusion: pass
...
>>> isinstance(Confusion, object)
Run Code Online (Sandbox Code Playgroud)
如果您考虑一下,这是有道理的 - 您可能已经创建了类级变量:
>>> class Counter:
... count = 0
... def __init__(self):
... Counter.count += 1
... print(self.count)
...
>>> Counter()
1
<__main__.Counter object at 0x7fa03fca4518>
>>> Counter()
2
<__main__.Counter object at 0x7fa03fca4470>
>>> Counter()
3
<__main__.Counter object at 0x7fa03fca4518>
>>> Counter()
4
<__main__.Counter object at 0x7fa03fca4470>
>>> Counter.count
4
>>> Counter.__repr__(Counter)
'<type object at 0x1199738>'
Run Code Online (Sandbox Code Playgroud)
但正如最后一个示例所示(并在帖子中提到),类声明,您所得到的class SomeClass: pass,类的声明实际上是另一个类的实例。特别是,它是该类的一个实例type。调用该实例(我们称之为类)时将生成其自身的实例:
>>> Counter.__call__()
5
<__main__.Counter object at 0x7fa03fca4518>
Run Code Online (Sandbox Code Playgroud)
type那么这一切与和之间的关系有什么关系object呢?
好吧,在某个地方,python创建了一系列位object,type然后将它们连接在一起,这样
>>> type.__bases__
(<class 'object'>,)
>>> object.__bases__
()
Run Code Online (Sandbox Code Playgroud)
因为我目前不想查看源代码,所以我将猜测type首先创建的,并且object是从该类型生成的,并且type.__bases__设置为(class 'object'). type通过在和 之间创建这种循环关系object,它看起来就像是一直向下的海龟,而实际上最后两只海龟只是站在彼此之上。
我认为没有比文章描述更好的方法来解释这里发生的事情了——至少在经典的 OOP is-a/has-a 思维方式中,因为它实际上不是那样的事情。就像尝试在 2d 空间中绘制 3d 图形一样,您将会遇到问题。
它只是两组位,其中的一些位恰好是彼此的地址。
| 归档时间: |
|
| 查看次数: |
191 次 |
| 最近记录: |