在类中定义的所有函数都是对象的绑定方法,对象在调用绑定方法时会将自己作为参数传递给方法的第一个参数(即self)
在类中还可以定义基于类名访问的函数:静态函数和类函数。
静态函数使用装饰器@staticmethod定义;类函数使用@classmaethod定义。两者在使用方法上非常相似,只存在一些细微的差别:@classmethod装饰的函数必须使用类对象作为第一个参数,一般命名为cls;而@staticmethod装饰的函数则可以不传递任何函数。
静态方法和类方法是为类定制设计的,在使用的时候,可以直接通过类名或类实例对象去访问。
示例:
class Download: """下载类""" @staticmethod def download_image(image_file): print('下载%s下的图片' %(image_file)) @classmethod def dowload_movie(cls,movie_file): print('下载电影:%s' %(movie_file)) def dowload(self): print('下载方法') Download.download_image('file/123.png') Download.dowload_movie('file/abc.mp4') Down = Download() Down.dowload() 结果: 下载file/123.png下的图片 下载电影:file/abc.mp4 下载方法
在示例中我们分别定义可以通过类名访问的静态方法download_image()和类方法download_movie(),在类方法中需要显式的传递cls参数,cls参数表示传递的是类本身。
同时还定义了对象方法download(),对象函数中的self参数表示实例化对象本身。
staticmethod和classmethod的区别
staticmethod:无论是类调用还是类的实例化对象调用,都无法获取到类内部的属性和方法。
classmethod:无需实例化,可以调用类属性和类方法。
实用案例:
''' 需求: 通过面向对象编程的思路,定义三角形类,实现计算三角形的周长和面积。 技术分析: 第一步,定义一个‘三角形’类,通过传入3条边来构造三角形,并提供计算周长和面积的方法。由于传入的3条边未必能构造出来三角形对象, 因此可以先创建一个方法来验证3条边是否可以构成三角形,这个方法显然不是对象方法,因此在调用这个方法时三角形对象尚未创建出来 (因为还不知道这3条边能不能构成三角形)。 第二步,使用静态方法来解决三角形周长和面积的计算问题。 计算三角形的周长:周长h = 边a + 边b + 边c 计算三角形的面积: 已知三角形三边a,b,c,根据(海伦公式) (半周长p = (a+b+c)/2) 面积S = math.sqrt(半周长p *(半周长p-边a) *(半周长p-边b)* (半周长p-边c)),其中math.sqrt方法为开平方根。 ''' from math import sqrt class Triangle(object): def __init__(self,a,b,c): self._a = a self._b = b self._c = c @staticmethod def is_valid(a,b,c): return a+b > c and b+c > a and a+c > b # 计算周长 def perimeter(self): return self._a+self._b+self._c # 计算面积 def area(self): half = self.perimeter()/2 return sqrt(half * (half-self._a) * (half-self._b) * (half-self._c)) def main(): a,b,c = 3,4,5 # 静态方法和类方法都是通过给类发消息来调用的 if Triangle.is_valid(a,b,c): t = Triangle(a,b,c) print('三角形的周长为:%s'%(t.perimeter())) print('三角形的面积为:%s' %(t.area())) else: print('无法构成三角形') if __name__=='__main__': main() 结果: 三角形的周长为:12 三角形的面积为:6.0