Python中的"方法"是什么?

bri*_*ant 69 python methods

任何人都可以用非常简单的术语向我解释Python中的"方法"是什么?

在许多初学者的Python教程中,这个词的使用方式就像初学者已经知道Python的上下文中的方法一样.虽然我当然熟悉这个词的一般含义,但我不清楚这个术语在Python中的含义.所以,请向我解释一下"Pythonian"方法的用途.

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

Ric*_*dle 83

它是一个类的成员函数:

class C:
    def my_method(self):
        print "I am a C"

c = C()
c.my_method()  # Prints "I am a C"
Run Code Online (Sandbox Code Playgroud)

就那么简单!

(还有一些替代方法,允许你控制类和函数之间的关系.但我猜你的问题是你不是在问这个问题,而只是基本问题.)

  • 值得注意的是,实例必须手动传递给方法,按照惯例,它将作为"self"传递. (8认同)
  • @Silldrick:你可能意味着正确的事情,但你的评论意味着错误.在调用方法时,不需要显式/手动传递实例.但是该方法必须明确地接收它,即你必须手动为实例添加一个参数(是的,按惯例称为`self`). (7认同)
  • @AaronMcSmooth:AndiDog的答案肯定更完整.我很想知道@brilliant是否发现它"更好",或者*太完整了.有时一个简单的答案会更好.(因为我不喜欢被指责辱骂,我已经回答了CW.) (5认同)
  • @delnan - 是的,谢谢你的澄清 - 当我说手动传递我真正的意思是它需要被明确地作为参数接收,但它是隐式传递的. (4认同)
  • @辉煌.不要让简单的回答让你感到困惑.(略微)比"方法是一种功能"更多,但差异绝对至关重要.查看其他答案,并针对您不了解的任何内容发布新问题. (2认同)

And*_*Dog 40

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

class C:
    def method(self, possibly, other, arguments):
        pass # do something here
Run Code Online (Sandbox Code Playgroud)

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

1)绑定方法

# 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
Run Code Online (Sandbox Code Playgroud)

绑定方法是属于类实例的方法.在此示例中,instance.method绑定到调用的实例instance.每次调用bound方法时,实例都会自动作为第一个参数传递 - self通过约定调用.

2)未绑定的方法

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
Run Code Online (Sandbox Code Playgroud)

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

了解这种差异,您可以将函数/方法用作对象,例如传递方法.作为一个例子使用的情况下,可以想象的API,可以让你定义一个回调函数,但你要提供一个方法回调函数.没问题,只需self.myCallbackMethod作为回调传递,它将自动以实例作为第一个参数调用.这在像C++这样的静态语言中是不可能的(或者只能用于欺骗).

希望你明白这一点;)我认为你应该了解方法基础知识.您还可以阅读有关classmethod和staticmethod装饰器的更多信息,但这是另一个主题.


Kev*_*ham 24

在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.

一个常见的混淆点涉及以下方面:

import math
math.sqrt(81)
Run Code Online (Sandbox Code Playgroud)

是对象sqrt的方法math吗?不.这是您sqrt从math模块调用该功能的方式.使用的格式是module_name.function_name(),而不是object_name.method_name().一般情况下,只有这样才能在两种格式之间区分(视觉)是看在代码的其余部分,看看部分的时间段之前(math,my_list,my_string)被定义为一个对象或一个模块.


pep*_*epr 5

抱歉,但是 - 在我看来 - RichieHindle 所说的方法是完全正确的......

它是一个属于类成员的函数。

这是成为类成员的函数的示例。从那时起,它就充当了类的方法。让我们从空类和带有一个参数的普通函数开始:

>>> class C:
...     pass
...
>>> def func(self):
...     print 'func called'
...
>>> func('whatever')
func called
Run Code Online (Sandbox Code Playgroud)

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

>>> C.func = func
>>> o = C()
>>> o.func()
func called
Run Code Online (Sandbox Code Playgroud)

我们还可以使用调用该方法的替代方式:

>>> C.func(o)
func called
Run Code Online (Sandbox Code Playgroud)

Eveno.func的表现方式与类方法相同:

>>> o.func
<bound method C.func of <__main__.C instance at 0x000000000229ACC8>>
Run Code Online (Sandbox Code Playgroud)

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

>>> class A:
...     def func(self):
...         print 'aaa'
...
>>> a = A()
>>> a.func
<bound method A.func of <__main__.A instance at 0x000000000229AD08>>
>>> a.func()
aaa
Run Code Online (Sandbox Code Playgroud)

到目前为止,看起来是一样的。现在窃取功能:

>>> afunc = A.func
>>> afunc(a)
aaa    
Run Code Online (Sandbox Code Playgroud)

事实上,该方法不接受“任何”参数:

>>> 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)
Run Code Online (Sandbox Code Playgroud)

恕我直言,这不是反对method is a function that is a member of a class 的论点。

后来发现Alex Martelli的答案基本上是一样的。抱歉,如果您认为这是重复的:)