Python中类的方法有两种形式:
1、绑定方法和非绑定方法
绑定的概念主要与方法调用相关联,方法是类内部定义的函数(这意味着方法是类属性而不是实例属性),方法只有在其所属的类拥有实例时,才能被调用,当存在一个实例时,方法才被认为是绑定到那个实例了。任何一个方法定义中的第一个参数都是self变量,表示调用此方法的实例对象。
class Person(): def __init__(self,name,age): self.name = name self.age = age def talk(self): print "talk calling" p = Person('rhx',25) print p.talk
<bound method Person.talk of <__main__.Person instance at 0x027A4DF0>>
注意这里不是调用的p.talk(),对于另一种情况,定义的talk()函数中没有self变量
class Person(): def __init__(self,name,age): self.name = name self.age = age def talk(): print "talk calling" p = Person('rhx',25) print p.talk
<bound method Person.talk of <__main__.Person instance at 0x02814DF0>>
发现无论talk中是否带有self,实例化对象 p 均可以调用。这也说明了不管是类中的方法,还是类中定义的函数,默认情况下都是绑定给对象使用的,在实例中调用一个绑定的方法时,不需要手动的传入参数了。
class Person(): def __init__(self,name,age): self.name = name self.age = age def talk(): print "talk calling" p = Person('rhx',25) print Person.talk print p.talk
<unbound method Person.talk> #使用类名进行调用,为非绑定的方法 <bound method Person.talk of <__main__.Person instance at 0x02794DF0>> #使用实例化对象进行调用为绑定的方法
对于在talk中带有self变量的情形
class Person(): def __init__(self,name,age): self.name = name self.age = age def talk(self): print "talk calling" p = Person('rhx',25) print Person.talk() print p.talk()
TypeError: unbound method talk() must be called with Person instance as first argument (got nothing instead)
结果表明talk()调用时必须传入类的实例化对象,当类调用类中的方法时候,是不会进行自动传值的,也就是说,函数有几个参数,就得传递进去几个参数。如果想结果正常运行,那么在类名调用talk()的时候,将参数一一都传递进去。即:
print Person.talk(p)
class Person(): def __init__(self,name,age): self.name = name self.age = age def talk(): print "talk calling" p = Person('rhx',25) print Person.talk print p.talk()
print p.talk() TypeError: talk() takes no arguments (1 given)
从输出结果来看,Person来调用talk()方法时候,并不需要传递参数;而当对象来调用talk()的时候,由于对象调用自己的绑定方法,会自动将实例化对象当作第一个参数传递进去,所以,当类中talk()方法没有带参数时,而你又给它传递了一个,显然是会报错的。
综上所述,我们可以得出以下结论:
1.凡是类中的方法和函数,都是绑定给对象使用的;
2.绑定方法都有自动传值的功能。传递进去的值,就是对象本身。
3.如果类想调用绑定方法,就必须遵循函数的参数规则,有几个参数,就必须传递几个参数。
既然类中的方法都是绑定给对象使用的,那么有没有方法是绑定给类使用的呢?
2、静态方法和类方法
既然类中的方法,默认都是绑定给对象使用,那么,我们要采取一点措施,将类中的绑定方法解除对象绑定关系,进而绑定到类上,通常的方法需要一个实例self作为第一个参数,并且对于(绑定的)方法调用来说,self时自动传递给这个方法的,而对于类方法而言,需要类而不是实例作为第一个参数,它是由解释器传给方法。在python中,引入了@classmethod方法,将类中的方法绑定到类身上。
class Person(): def __init__(self,name,age): self.name = name self.age = age @classmethod #talk = classmethod(talk) def talk(cls): #cls即为类自身 print "talk calling" p = Person('rhx',25) print Person.talk() print p.talk()
这里之所以实例化对象调用类方法也可行的原因就是类方法也有一个参数cls,实例化对象调用的时候将实例化对象self传递给形参cls。类中方法默认都是绑定给对象使用,当对象调用绑定方法时,会自动将对象作为第一个参数传递进去;而类来调用,则必须遵循函数参数一一对应的规则,有几个参数,就必须传递几个参数。如果一个方法是用了@classmethod装饰器,那么這个方法绑定到类身上,不管是对象来调用还是类调用,都会将类作为第一个参数传递进去。
在前面的例子中,对于没有参数的talk,使用类调用的时候是
class Person(): def __init__(self,name,age): self.name = name self.age = age def talk(): print "talk calling" p = Person('rhx',25) print Person.talk() print p.talk()
print Person.talk() TypeError: unbound method talk() must be called with Person instance as first argument (got nothing instead)
但是传递一个实例化对象p的时候
print Person.talk(p)
仍然会有问题,因为方法talk本来就没有参数
print Person.talk(p) TypeError: talk() takes no arguments (1 given)
这个时候需要静态方法
class Person():
def __init__(self,name,age):
self.name = name
self.age = age
@staticmethod #talk = staticmethod(talk)
def talk(): #不能传递类或实例相关参数,如cls或者self,但是可以传递其它参数
print "talk calling"
p = Person('rhx',25)
print Person.talk()
print p.talk()
共同学习,写下你的评论
评论加载中...
作者其他优质文章