对象方法与函数的区别只在于额外的self变量,因为方法跟对象相关,所以self相当于是方法的占位实例对象。
方法初识
方法是对象所具有的行为,是面向对象中的概念,基本功能同函数差不多。
1 >>> def A(): 2 print 'this is a function' 3 4 5 >>> class B: 6 def f(self): 7 print 'this is a method' 8 #def f1(): #试用无self的函数,输出以下内容 9 #print 'no self' 10 11 >>> B.f #通过类名B获取类方法属性f 12 <unbound method B.f> 13 >>> B().f #通过实例获取类方法属性f 14 <bound method B.f of <__main__.B instance at 0x026AB558>> 15 >>> type(B.f) 16 <type 'instancemethod'> 17 >>> type(B().f) 18 <type 'instancemethod'> 19 >>> B.__dict__ #'f'是一个函数对象,当通过类来获取函数属性的时候,得到的是非绑定方法对象,当通过实例来获取函数属性的时候,得到的是绑定方法对象 20 {'__module__': '__main__', '__doc__': None, 'f': <function f at 0x026E70F0>} 21 22 >>> A 23 <function A at 0x026E5CF0> 24 >>> b = B() 25 >>> b.f 26 <bound method B.f of <__main__.B instance at 0x026AB288>> 27 28 >>> b.f2 = A #定义实例对象b的f2属性为函数A 29 >>> b.f2 30 <function A at 0x026E5CF0> 31 >>> b.__dict__ 32 {'f2': <function A at 0x026E5CF0>} 33 34 >>> B.f3 = A #定义类对象B的f3属性为函数A 35 >>> B.f3 36 <unbound method B.A> 37 >>> B.__dict__ 38 {'__module__': '__main__', 'f3': <function A at 0x026E5CF0>, '__doc__': None, 'f': <function f at 0x026E70F0>}
深入了解
1.实例方法:没有修饰符,至少使用一个self参数,无self无法调用
1 >>> class B: 2 def f(self): 3 print 'this is a method' 4 def f1(): 5 print 'no self' 6 7 >>> B.f 8 <unbound method B.f> 9 >>> B.f1 10 <unbound method B.f1> 11 >>> B().f 12 <bound method B.f of <__main__.B instance at 0x022B4AD0>> 13 >>> B().f1 14 <bound method B.f1 of <__main__.B instance at 0x0288AC10>> 15 16 >>> B().f() #等价于B.f(B()) 17 this is a method 18 >>> B().f1() #没self无法调用 19 20 Traceback (most recent call last): 21 File "<pyshell#17>", line 1, in <module> 22 B().f1() 23 TypeError: f1() takes no arguments (1 given)
2.类方法:在方法前面加上@classmethod修饰符,至少使用一个参数cls,作用是代表改类本身。
1 >>> class B: 2 @classmethod 3 def f1(cls): 4 print 'classmethod have cls arg' 5 6 7 >>> B.f1() 8 classmethod have cls arg 9 >>> B().f1() 10 classmethod have cls arg 11 >>> B.f1 12 <bound method classobj.f1 of <class __main__.B at 0x028A2458>> 13 >>> B().f1 14 <bound method classobj.f1 of <class __main__.B at 0x028A2458>>
3.静态方法:在方法前面加上@staticmethod修饰符,无内定参数。
1 >>> class B: 2 @staticmethod 3 def f(): 4 print 'static method' 5 6 7 >>> B.f() 8 static method 9 >>> B().f() 10 static method 11 >>> B.f 12 <function f at 0x02897C30> 13 >>> B().f 14 <function f at 0x02897C30>
实例方法,类方法,静态方法区别
1.实例方法通过实例.方法名()或类名.方法名(实例)的形式调用,类方法和静态方法通过实例.方法名()或类名.方法名()的形式调用;
2.实例方法仅可以被类实例调用,类方法和静态方法可以被类和类实例调用;
3.实例方法可以调用类变量和实例变量,类方法仅可以调用类变量,静态方法都不可以调用;
1 class MyTest: 2 val = 3 #类变量 3 def func(self): 4 print self.val #self.val实例变量 5 6 @classmethod 7 def cfunc(cls): 8 print cls.val 9 10 @staticmethod 11 def sfunc(a, b): 12 print "static method:", a, " + ", b, "=", a + b 13 14 15 >>> MyTest.func() #实例方法只能通过实例访问类变量 16 17 Traceback (most recent call last): 18 File "<pyshell#3>", line 1, in <module> 19 MyTest.func() 20 TypeError: unbound method func() must be called with MyTest instance as first argument (got nothing instead) 21 >>> MyTest.cfunc() #类方法可以访问类变量 22 3 23 >>> MyTest.sfunc(2,3) 24 static method: 2 + 3 = 5 25 >>> t = MyTest() #等价于MyTest.func(MyTest()) 26 >>> t.func() 27 3