Python中的“方法”是什么?

What is a “method” in Python?

有人能用非常简单的术语向我解释一下Python中的"方法"是什么?

在许多针对初学者的Python教程中,这个词的使用方式就像初学者已经知道Python上下文中的方法一样。虽然我当然熟悉这个词的一般含义,但我不知道这个词在python中的含义。所以,请向我解释一下"Python"法是关于什么的。

一些非常简单的示例代码将非常受欢迎,因为一张图片价值千言万语。


它是一个类的成员函数:

1
2
3
4
5
6
class C:
    def my_method(self):
        print"I am a C"

c = C()
c.my_method()  # Prints"I am a C"

很简单!

(还有一些可选的方法,允许您控制类和函数之间的关系。但从你的问题来看,我猜你不是在问这个问题,而是基本问题。)


方法是将类实例作为第一个参数的函数。方法是类的成员。

1
2
3
class C:
    def method(self, possibly, other, arguments):
        pass # do something here

正如您想知道它在Python中的具体含义一样,可以区分绑定方法和未绑定方法。在Python中,所有函数(以及方法)都是可以传递和"播放"的对象。因此,未绑定方法和绑定方法之间的区别是:

1)绑定方法

1
2
3
4
5
6
7
8
# Create an instance of C and call method()
instance = C()

print instance.method # prints '<bound method C.method of <__main__.C instance at 0x00FC50F8>>'
instance.method(1, 2, 3) # normal method call

f = instance.method
f(1, 2, 3) # method call without using the variable 'instance' explicitly

绑定方法是属于类实例的方法。在本例中,instance.method与名为instance的实例绑定。每次调用绑定方法时,都会自动将实例作为第一个参数传递,该参数按约定称为self

2)未绑定方法

1
2
3
4
5
6
7
print C.method # prints '<unbound method C.method>'
instance = C()
C.method(instance, 1, 2, 3) # this call is the same as...
f = C.method
f(instance, 1, 2, 3) # ..this one...

instance.method(1, 2, 3) # and the same as calling the bound method as you would usually do

当您访问C.method时(方法在类内而不是在实例内),您会得到一个未绑定的方法。如果要调用它,则必须将实例作为第一个参数传递,因为该方法未绑定到任何实例。

知道这一区别后,您可以将函数/方法用作对象,例如传递方法。作为一个示例用例,设想一个允许您定义回调函数的API,但是您希望提供一个方法作为回调函数。没问题,只需将self.myCallbackMethod作为回调传递,它将以实例作为第一个参数自动调用。这在C++等静态语言中是不可能的(或者只有欺骗)。

希望你能理解这一点;)我认为这就是你应该了解的关于方法基础知识的全部内容。您还可以阅读更多关于classmethodstaticmethod装饰器的内容,但这是另一个主题。


在Python中,方法是一个函数,因为对象的类型而对给定对象可用。

例如,如果创建my_list = [1, 2, 3],则可以将append方法应用于my_list,因为它是一个python列表:my_list.append(4)。所有列表都有一个append方法,因为它们是列表。

另一个例子是,如果创建my_string = 'some lowercase text',那么可以将upper方法应用于my_string,因为它是一个python字符串:my_string.upper()

列表没有upper方法,字符串没有append方法。为什么?因为只有为特定对象显式定义了方法,并且Python的开发人员(到目前为止)已经决定这些特定对象不需要这些特定方法,才存在这些方法。

要调用方法,格式为object_name.method_name(),方法的任何参数都列在括号中。方法隐式地作用于被命名的对象,因此一些方法没有任何声明的参数,因为对象本身是唯一必要的参数。例如,my_string.upper()没有列出任何参数,因为唯一需要的参数是对象本身,my_string

一个常见的混淆点是:

1
2
import math
math.sqrt(81)

sqrtmath对象的方法吗?不,这是从math模块调用sqrt函数的方式。使用的格式是module_name.function_name(),而不是object_name.method_name()。一般来说,区分这两种格式(视觉上)的唯一方法是查看代码的其余部分,并查看句点之前的部分(mathmy_listmy_string是否定义为对象或模块。


抱歉,但是——在我看来——里奇·辛德尔说这个方法完全正确……

It's a function which is a member of a class.

下面是成为类成员的函数的示例。从那时起,它就作为类的一个方法运行。让我们从空类开始,从普通函数开始,用一个参数:

1
2
3
4
5
6
7
8
>>> class C:
...     pass
...
>>> def func(self):
...     print 'func called'
...
>>> func('whatever')
func called

现在我们向C类添加一个成员,它是对函数的引用。之后,我们可以创建类的实例,并像在类中定义的那样调用它的方法:

1
2
3
4
>>> C.func = func
>>> o = C()
>>> o.func()
func called

我们还可以使用另一种方法调用该方法:

1
2
>>> C.func(o)
func called

o.func甚至表现出与class方法相同的方式:

1
2
>>> o.func
<bound method C.func of <__main__.C instance at 0x000000000229ACC8>>

我们可以尝试相反的方法。让我们定义一个类并将其方法窃取为一个函数:

1
2
3
4
5
6
7
8
9
>>> class A:
...     def func(self):
...         print 'aaa'
...
>>> a = A()
>>> a.func
<bound method A.func of <__main__.A instance at 0x000000000229AD08>>
>>> a.func()
aaa

到目前为止,它看起来是一样的。现在函数窃取:

1
2
3
>>> afunc = A.func
>>> afunc(a)
aaa

事实上,该方法不接受"whatever"参数:

1
2
3
4
5
>>> afunc('whatever')
Traceback (most recent call last):
  File"<stdin>", line 1, in <module>
TypeError: unbound method func() must be called with A instance as first
  argument (got str instance instead)

imho,这不是反对方法的参数,而是作为类成员的函数。

后来发现亚历克斯·马泰利的回答基本上是一样的。对不起,如果你认为是重复的话:)


如果你认为一个物体类似于一个名词,那么一个方法类似于一个动词。在对象(即字符串或列表)后面使用方法将方法的操作应用于该对象。


http://docs.python.org/2/tutorial/classes.html方法对象

Usually, a method is called right after it is bound:

1
x.f()

In the MyClass example, this will return the string 'hello world'.
However, it is not necessary to call a method right away: x.f is a
method object, and can be stored away and called at a later time. For
example:

1
2
3
xf = x.f
while True:
    print xf()

will continue to print hello world until the end of time.

What exactly happens when a method is called? You may have noticed
that x.f() was called without an argument above, even though the
function definition for f() specified an argument. What happened to
the argument? Surely Python raises an exception when a function that
requires an argument is called without any — even if the argument
isn’t actually used...

Actually, you may have guessed the answer: the special thing about
methods is that the object is passed as the first argument of the
function. In our example, the call x.f() is exactly equivalent to
MyClass.f(x). In general, calling a method with a list of n arguments
is equivalent to calling the corresponding function with an argument
list that is created by inserting the method’s object before the first
argument.

If you still don’t understand how methods work, a look at the
implementation can perhaps clarify matters. When an instance attribute
is referenced that isn’t a data attribute, its class is searched. If
the name denotes a valid class attribute that is a function object, a
method object is created by packing (pointers to) the instance object
and the function object just found together in an abstract object:
this is the method object. When the method object is called with an
argument list, a new argument list is constructed from the instance
object and the argument list, and the function object is called with
this new argument list.