Python中的“方法”是什么?

时间:2010-09-24 12:07:07

标签: python methods

请允许任何人以非常简单的方式向我解释Python中的“方法”是什么?

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

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

7 个答案:

答案 0 :(得分:79)

这是一个类的成员函数:

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

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

这很简单!

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

答案 1 :(得分:37)

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

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

如果您想知道它在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

绑定方法是属于类实例的方法。在此示例中,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

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

了解这种差异,您可以将函数/方法用作对象,例如传递方法。作为示例用例,假设一个API允许您定义回调函数,但是您想要提供一个方法作为回调函数。没问题,只需传递self.myCallbackMethod作为回调,它将自动以实例作为第一个参数调用。这在C ++这样的静态语言中是不可能的(或者只有诡计)。

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

答案 2 :(得分:23)

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

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

答案 3 :(得分:2)

抱歉,但是 - 在我看来 - RichieHindle完全正确地说这种方法......

  

这是一个类的成员。

以下是成为类成员的函数示例。从那时起,它就像一个类的方法。让我们从 empty 类和带有一个参数的正常函数开始:

>>> class C:
...     pass
...
>>> def func(self):
...     print 'func called'
...
>>> func('whatever')
func called

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

>>> C.func = func
>>> o = C()
>>> o.func()
func called

我们也可以使用另一种调用方法的方法:

>>> C.func(o)
func called

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

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

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

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

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

>>> afunc = A.func
>>> afunc(a)
aaa    

事实是,该方法不接受'无论'的论点:

>>> 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)

恕我直言,这不是反对方法的论据是一个属于类的成员的函数。

后来发现 Alex Martelli's answer基本上都是这样说的。对不起,如果你认为它重复:)

答案 4 :(得分:0)

http://docs.python.org/2/tutorial/classes.html#method-objects

  

通常,一个方法在绑定后立即被调用:

x.f()
     

在MyClass示例中,这将返回字符串'hello world'。   但是,没有必要立即调用方法:x.f是a   方法对象,可以存储起来并在以后调用。对于   例如:

xf = x.f
while True:
    print xf()
     

将继续打印你好世界,直到时间结束。

     

调用方法时究竟发生了什么?你可能已经注意到了   上面没有参数调用x.f(),即使是   f()的函数定义指定了一个参数。发生了什么事   这个论点?当一个函数时,Python肯定会引发异常   需要一个没有任何参数的参数 - 即使是参数   实际上并未使用......

     

实际上,你可能已经猜到了答案:特别的事情   方法是将对象作为第一个参数传递   功能。在我们的示例中,调用x.f()完全等效于   MyClass.f(X)。通常,使用n个参数列表调用方法   相当于用参数调用相应的函数   通过在第一个方法之前插入方法的对象而创建的列表   参数。

     

如果你仍然不明白方法是如何工作的,那么看看   实施也许可以澄清问题。当一个实例属性   引用的不是数据属性,搜索其类。如果   name表示一个有效的class属性,它是一个函数对象,a   方法对象是通过打包(指向)实例对象来创建的   和一个在抽象对象中一起找到的函数对象:   这是方法对象。用方法调用方法对象时   参数列表,从实例构造一个新的参数列表   对象和参数列表,以及调用函数对象   这个新的参数列表。

答案 5 :(得分:0)

如果您认为对象与名词相似,那么方法与动词相似。在对象(即字符串或列表)之后立即使用方法,以将方法的操作应用于对象。

答案 6 :(得分:0)

要了解方法,您必须首先考虑面向对象的编程: 让我们上汽车课。所有汽车都有一些共同点,并且使它们与众不同,例如,所有汽车都有4个轮子,车门和一个方向盘...。但是您的每辆汽车(我们称之为my_toyota)是红色的,从0到60 5.6秒 此外,汽车当前位于我的房子里,门已锁,后备箱是空的……所有这些都是my_toyota实例的属性。 your_honda可能正在路上,到处都是杂货...

不过,您可以在汽车上做一些事情。您可以驾驶它,可以打开门,可以装载它。您可以用汽车执行的操作就是汽车的方法,它们会更改特定实例的属性。

您将做为伪代码:

my_toyota.drive(shop)

将位置从我的家更改为商店,或者

my_toyota.load([milk, butter, bread]

现在,行李箱中已装满[牛奶,黄油,面包]。

因为这样的方法实际上是充当对象一部分的功能:

class Car(vehicle)
    n_wheels = 4

    load(self, stuff):
    '''this is a method, to load stuff into the trunk of the car'''
        self.open_trunk
        self.trunk.append(stuff)
        self.close_trunk

代码将是:

my_toyota = Car(red)
my_shopping = [milk, butter, bread]
my_toyota.load(my_shopping)