2016-04-22 40 views
3

在蟒蛇,staticmethod s为“只是功能”,并且可以参考我给他们两种不同的方式:Python classmethods:实例成员和类成员之间有什么区别?

>>> class A: 
...  @staticmethod 
...  def f(): 
...   pass 
... 
>>> a=A() 
>>> A.f 
<function A.f at 0x7f20f8cd3f28> 
>>> a.f 
<function A.f at 0x7f20f8cd3f28> 
>>> a.f is A.f 
True 

两个a.fA.f是指同一个对象,这恰好是“公正的名字一个功能“。大。

现在,说我有一个classmethod

>>> class B: 
...  @classmethod 
...  def f(cls): 
...   pass 
... 
>>> b=B() 
>>> b.f is B.f 
False 

我知道b.fB.f功能:他们是约束mothods。这意味着cls参数是隐含的,并且始终等于B。正因为如此,我会明白,如果B2B一个子类,B2().f is B().f会是假的,因为他们绑定不同cls参数的方法。但我不明白为什么B().f is B.f收益率为False。他们不应该是相同的对象,就像A().fA.f

编辑:这个问题是不一样的“What is the difference between @staticmethod and @classmethod in Python?”。我知道staticmethodclassmethod之间的区别。我想知道一件具体的事情,这在“伞”问题中没有涉及。

+0

一个类就像一个定义。 '实例'是该定义的实际使用。所以'class'是一个配方,''instance'就是蛋糕。由于配方不是蛋糕,只有关于如何制作蛋糕的说明,它们是不一样的。 – DuckPuncher

+0

@DuckPuncher你读过我的问题了吗?我想知道为什么'B().f是B.f'是假的,'A().f是A.f'是真的。 – fonini

+1

另请参见“用户定义的方法”:https://docs.python.org/2/reference/datamodel.html#types –

回答

4

B().fB.f是不同的对象,因为每当您通过属性访问引用非静态方法时,Python会创建一个新的绑定方法对象。

例如,B.f is B.fFalse

>>> B.f is B.f 
False 

同样,你会得到一个新的方法的对象即使该实例保持不变:

>>> b = B() 
>>> b.f is b.f 
False 

@staticmethod创建一个新的静态方法的对象,但

当一个静态方法对象是从一个类或一个类 实例中检索到的,实际返回的对象是被包装的对象,它不受任何进一步转换上。

(从Data model

在这种情况下A.f始终返回相同f功能对象。

+1

FWIW,'b = B(); b.f是b.f'也是假的。 –

相关问题