请允许任何人以非常简单的方式向我解释Python中的“方法”是什么?
在初学者的许多Python教程中,这个词的使用方式就像初学者已经知道Python的上下文中的方法一样。虽然我当然熟悉这个词的一般含义,但我不清楚这个术语在Python中的含义。所以,请向我解释一下“Pythonian”方法的用途。
一些非常简单的示例代码将非常受欢迎,因为图片值得千言万语。
答案 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 ++这样的静态语言中是不可能的(或者只有诡计)。
希望你明白这一点;)我认为你应该了解方法基础知识。您还可以阅读有关classmethod
和staticmethod
装饰器的更多信息,但这是另一个主题。
答案 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)
sqrt
是math
对象的方法吗? 否。这是您从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)