Python中的对象实例是否每个都有各自的方法实例?

时间:2018-06-28 14:57:56

标签: python-3.x

说我有一堂课:

class Thing:
    i = 0
    def __init__(self, a):
        self.a = a
    def doStuff(self):
        print(self.a)
    @classmethod
    def doClassThings(cls):
        cls.i += 1

然后,我从此类创建了两个对象:

obj1 = Thing(2)
obj2 = Thing(4)

此时程序的内存中有多少个“ doStuff”和“ init ”方法实例?对于两个对象中的每一个,是否都有这些方法的单独但相同的副本?还是只有两个事物实例共享一个“ doStuff”方法?

对于类方法,我的理解是每个类方法只有一个实例,可以通过编写来调用

Thing.doClassThings()

整个班级也只有一个“ i”变量。这是正确的吗?

无论哪种方式,就实例方法而言,就内存使用而言,我都不知道Python如何工作。我真的很不喜欢这些实例方法有副本的想法,因为它们是相同的,而且这是多余的。

最后,如果Python确实为该类的每个实例创建了每个实例函数的多个副本,那么我该如何编写不这样做的代码?

1 个答案:

答案 0 :(得分:0)

请注意,我不知道具体的规格,以下只是我的观察和预测。

  

此时程序的内存中有多少个“ doStuff”和“ init”方法实例?对于两个对象中的每一个,是否都有这些方法的单独但相同的副本?还是只有两个事物实例共享一个“ doStuff”方法?

如果您打印doStuff__init__,则会看到它们具有不同的内存地址: print(ob1.doStuff)(不要在后面加上括号,因为我们不想调用该函数)给了我<bound method Thing.doStuff of <__main__.Thing object at 0x0000026FE45C9128>>,但是print(obj.doStuff)打印了<bound method Thing.doStuff of <__main__.Thing object at 0x0000026FE45C9160>>;这两个功能具有不同的存储器地址。因此,确实有两个单独但相同的方法副本。

  

对于类方法,我的理解是每个类方法只有一个实例,可以通过编写Thing.doClassThings()

来调用

这应该是正确的(打印函数不会给我地址,但是使用==比较两个函数会返回True。)。尽管您也可以从对象本身(例如obj.doClassThings())调用该函数。

  

整个班级也只有一个“ i”变量。这是正确的吗?

这似乎有点不可思议:

print(obj1.i, obj2.i, Thing.i)  # prints 0 0 0, as expected
Thing.doClassThings()
print(obj1.i, obj2.i, Thing.i)  # prints 1 1 1
obj1.i += 1
print(obj1.i, obj2.i, Thing.i)  # prints 2 1 1
Thing.doClassThings()
print(obj1.i, obj2.i, Thing.i)  # prints 2 2 2

就像您从对象中更改i一样,它会创建自己的i,而不连接到其余对象。