使用Python中的类定义调用实例方法

时间:2018-07-24 18:52:13

标签: python class instance-methods

最近,我一直在研究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'>

2 个答案:

答案 0 :(得分:1)

在“评论”部分中向带领我的每个人提供的支持。


这个问题的答案取决于Python的两个基本原理:

  1. 鸭式
  2. 一切都是对象

实际上,即使self是Python引用当前类实例的惯用法,但从技术上讲,由于Python处理键入的方式,您可以传递所需的任何对象。

现在,另一个让我感到困惑的地方是,我没有在第二个示例中创建对象。但是,事实是,Foo在内部已经是一个对象。

可以像这样凭经验进行测试,

print(type(Foo))
<class 'type'>

因此,我们现在知道Foo是类type的实例,因此即使它不是 instance 的实例,也可以作为self传递本身。

基本上,如果我将self当作Foo方法中的test对象一样进行操作,则像第二个示例那样调用它时,我将遇到问题。

答案 1 :(得分:0)

关于您的问题(和答案)的一些注释。首先,一切都是对象。甚至一个类都是一个对象,因此,存在该类的类(称为 metaclass ),在这种情况下为type

第二,与您的情况更相关。方法或多或少是 class ,而不是 instance 属性。在python中,当您有一个对象objClass的实例,并且您访问obj.x时,python首先查看obj,然后查看Class。这就是从实例访问方法时发生的情况,它们只是特殊的类属性,因此可以从实例和类中进行访问。并且,由于您没有使用应传递给self函数的test(self)的任何实例属性,因此传递的对象是无关紧要的。

要深入了解,如果您不熟悉,请阅读描述符协议。它解释了很多有关python如何工作的信息。它允许python类和对象本质上是字典,具有一些特殊属性(非常类似于javascript对象和方法)

关于类实例化,请参见关于__new__元类