最近,我一直在研究Python的类实例化过程,以真正了解在创建类实例时内幕会发生什么。但是,在玩测试代码时,我遇到了一些我不理解的东西。
考虑这个假类
class Foo():
def test(self):
print("I'm using test()")
通常,如果我想使用Foo.test
instance方法,我会创建一个Foo
的实例并像这样显式地调用它,
foo_inst = Foo()
foo_inst.test()
>>>> I'm using test()
但是,我发现以这种方式调用它最终会得到相同的结果,
Foo.test(Foo)
>>>> I'm using test()
在这里,我实际上并没有创建实例,但是我仍在访问Foo
的实例方法。为什么以及如何在Python上下文中起作用?我的意思是self
通常是指该类的当前实例,但是在这种情况下,我并不是从技术上创建类实例。
print(Foo()) #This is a Foo object
>>>><__main__.Foo object at ...>
print(Foo) #This is not
>>>> <class '__main__.Foo'>
答案 0 :(得分:1)
在“评论”部分中向带领我的每个人提供的支持。
这个问题的答案取决于Python的两个基本原理:
实际上,即使self
是Python引用当前类实例的惯用法,但从技术上讲,由于Python处理键入的方式,您可以传递所需的任何对象。
现在,另一个让我感到困惑的地方是,我没有在第二个示例中创建对象。但是,事实是,Foo
在内部已经是一个对象。
可以像这样凭经验进行测试,
print(type(Foo))
<class 'type'>
因此,我们现在知道Foo
是类type
的实例,因此即使它不是 instance 的实例,也可以作为self
传递本身。
基本上,如果我将self
当作Foo
方法中的test
对象一样进行操作,则像第二个示例那样调用它时,我将遇到问题。
答案 1 :(得分:0)
关于您的问题(和答案)的一些注释。首先,一切都是对象。甚至一个类都是一个对象,因此,存在该类的类(称为 metaclass ),在这种情况下为type
。
第二,与您的情况更相关。方法或多或少是 class ,而不是 instance 属性。在python中,当您有一个对象obj
,Class
的实例,并且您访问obj.x
时,python首先查看obj
,然后查看Class
。这就是从实例访问方法时发生的情况,它们只是特殊的类属性,因此可以从实例和类中进行访问。并且,由于您没有使用应传递给self
函数的test(self)
的任何实例属性,因此传递的对象是无关紧要的。
要深入了解,如果您不熟悉,请阅读描述符协议。它解释了很多有关python如何工作的信息。它允许python类和对象本质上是字典,具有一些特殊属性(非常类似于javascript对象和方法)
关于类实例化,请参见关于__new__
和元类。