下面的类方法有什么区别?

是不是一个是静态的,另一个不是?

class Test(object):
  def method_one(self):
    print "Called method_one"

  def method_two():
    print "Called method_two"

a_test = Test()
a_test.method_one()
a_test.method_two()

当前回答

method_two的定义无效。当你调用method_two时,你会得到TypeError: method_two()接受0个位置参数,但1个是由解释器给出的。

当您像a_test.method_two()那样调用实例方法时,它是一个有界函数。它自动接受指向Test实例的self作为第一个参数。通过self参数,实例方法可以自由地访问和修改同一对象上的属性。

其他回答

>>> class Class(object):
...     def __init__(self):
...         self.i = 0
...     def instance_method(self):
...         self.i += 1
...         print self.i
...     c = 0
...     @classmethod
...     def class_method(cls):
...         cls.c += 1
...         print cls.c
...     @staticmethod
...     def static_method(s):
...         s += 1
...         print s
... 
>>> a = Class()
>>> a.class_method()
1
>>> Class.class_method()    # The class shares this value across instances
2
>>> a.instance_method()
1
>>> Class.instance_method() # The class cannot use an instance method
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unbound method instance_method() must be called with Class instance as first argument (got nothing instead)
>>> Class.instance_method(a)
2
>>> b = 0
>>> a.static_method(b)
1
>>> a.static_method(a.c) # Static method does not have direct access to 
>>>                      # class or instance properties.
3
>>> Class.c        # a.c above was passed by value and not by reference.
2
>>> a.c
2
>>> a.c = 5        # The connection between the instance
>>> Class.c        # and its class is weak as seen here.
2
>>> Class.class_method()
3
>>> a.c
5

在Python中,绑定方法和未绑定方法是有区别的。

基本上,调用一个成员函数(比如method_one),一个绑定函数

a_test.method_one()

被翻译为

Test.method_one(a_test)

例如,调用一个未绑定的方法。正因为如此,调用你的method_two版本将会失败并返回TypeError

>>> a_test = Test() 
>>> a_test.method_two()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: method_two() takes no arguments (1 given) 

您可以使用装饰器更改方法的行为

class Test(object):
    def method_one(self):
        print "Called method_one"

    @staticmethod
    def method_two():
        print "Called method two"

装饰器告诉内置的默认元类类型(类的类,参见这个问题)不要为method_two创建绑定方法。

现在,你可以直接在实例或类上调用静态方法:

>>> a_test = Test()
>>> a_test.method_one()
Called method_one
>>> a_test.method_two()
Called method_two
>>> Test.method_two()
Called method_two

The second one won't work because when you call it like that python internally tries to call it with the a_test instance as the first argument, but your method_two doesn't accept any arguments, so it wont work, you'll get a runtime error. If you want the equivalent of a static method you can use a class method. There's much less need for class methods in Python than static methods in languages like Java or C#. Most often the best solution is to use a method in the module, outside a class definition, those work more efficiently than class methods.

当调用类成员时,Python自动使用对象引用作为第一个形参。变量self实际上没有任何意义,它只是一种编码约定。如果你愿意,可以叫它滴水怪。也就是说,对method_two的调用将引发TypeError,因为Python会自动尝试将一个参数(对其父对象的引用)传递给一个定义为没有参数的方法。

为了让它工作,你可以把这个附加到你的类定义:

method_two = staticmethod(method_two)

或者您可以使用@staticmethod函数装饰器。

请阅读Guido First Class的文档,清楚地解释了Unbound, Bound方法是如何诞生的。