• 方法


    定义在类中的函数称为方法。根据调用的方式不同,分为:

    • 对象方法
    • 类方法
    • 静态方法
    • 魔术方法。

    对象方法

    定义在类中的普通函数,一般通过对象调用称为对象方法。

    对象方法的定义

    为了讲清楚对象方法的定义和调用,先看下面的案例

    案例:

    定义函数my_print,它接收一个Point对象,然后打印这个点的x,y坐标。

    def my_print(point):
        print('({},{})'.format(point.x, point.y))
        
    p = Point()
    p.x = 1
    p.y = 2
    my_print(p)
    

    输出:

    (1,2)
    

    在定义函数distance,它接收两个Point对象,然后返回这两个点的距离。

    def distance(p1, p2):
        return ((p1.x-p2.x)**2 + (p1.y-p2.y)**2)**0.5
    
    p1 = Point()			# 实例化
    p2 = Point()			# 实例化
    p1.x = 1				# 赋值x坐标
    p1.y = 2				# 赋值y坐标
    p2.x = 3				# 赋值x坐标
    p2.y = 4				# 赋值y坐标
    res = distance(p1,p2)
    print(res)
    

    输出:

    2.8284271247461903
    

    观察上面的两个函数,发现它们都接收一个或多个Point的对象作为参数。为了显式的加强这样的联系,我们可以将它们定义在Point的类中。

    class Point:
        """
        表示平面坐标系中的一个点
        """
        name = '点'
    
        def my_print(point):
            print('({},{})'.format(point.x, point.y))
    
        def distance(p1, p2):
            return ((p1.x-p2.x)**2 + (p1.y-p2.y)**2)**0.5
    

    对象方法的调用

    对象方法像属性一样,可以通过句点法进行调用。

    类.方法名(参数)
    对象.方法名(参数)
    

    通过类调用时,和普通函数没有区别。

    # 接上面的代码
    # 更新了类,再次实例化对象
    point = Point()
    point.x = 1
    point.y = 2
    p1 = Point()
    p2 = Point()
    p1.x = 1
    p1.y = 2
    p2.x = 3
    p2.y = 4
    

    通过类调用(一般不会这么调用)

    Point.my_print(point)
    res = Point.distance(p1, p2)
    print(res)
    

    输出:

    (1,2)
    2.8284271247461903
    

    通过对象调用对象方法时,对象本身会被隐式的传给方法的第一个参数。

    point.my_print()
    res = p1.distance(p2)
    print(res)
    

    输出:

    (1,2)
    2.8284271247461903
    

    因此,定义对象方法会习惯性的把第一个形参定义为self,表示调用对象本身

    class Point:
        """
        表示平面坐标系中的一个点
        """
        name = '点'
    
        def my_print(self):
            print('({},{})'.format(self.x, self.y))
    
        def distance(self, p2):
            return ((self.x-p2.x)**2 + (self.y-p2.y)**2)**0.5
    

    类方法

    在类中通过装饰器classmethod来定义类方法。

    调用类方法时,会把类自己作为第一个实参,就像一个实例方法把实例自己作为第一个实参。

    案例:

    定义一个类方法base_point用来返回坐标原点。

    class Point:
        """
        表示平面坐标系中的一个点
        """
        name = '点'
    
        def my_print(self):
            print('({},{})'.format(self.x, self.y))
    
        def distance(self, p2):
            return ((self.x-p2.x)**2 + (self.y-p2.y)**2)**0.5
        
        @classmethod
        def base_point(cls):
            bp = cls()
            bp.x = 0
            bp.y = 0
            return bp
    

    通过类本身或者是该类的实例都可以调用类方法。

    p = Point()
    bp1 = p.base_point()
    bp1.my_print()
    bp2 = Point.base_point()
    bp2.my_print()
    

    输出:

    (0,0)
    (0,0)
    

    特殊方法(魔术方法)

    在类中可以定义一些特殊的方法用来实现特殊的功能,也称为魔术方法。这些方法一般都以双下划线__开头。

    __init__

    __init__又叫构造方法,初始化方法,在调用类名实例化对象时,构造方法会被调用,类名括号()后的参数会传递给构造方法,对象属性一般在这个方法中定义。

    案例:

    上面案例中的Point类实例化后,需要手动创建对象属性xy,这显然容易出错和不规范,正确的做法应该是在构造方法中定义属性xy

    class Point:
        """
        表示平面坐标系中的一个点
        """
        name = '点'
        
        def __init__(self, x, y):
            self.x = x
            self.y = y
        
        def my_print(self):
            print('({},{})'.format(self.x, self.y))
    
        def distance(self, p2):
            return ((self.x-p2.x)**2 + (self.y-p2.y)**2)**0.5
        
        @classmethod
        def base_point(cls):
            return cls(0,0)
    
    # 实例化
    p1 = Point(1, 2)			# 实例化时传递参数给构造方法
    p2 = Point(x=3, y=4)
    
    p1.my_print()
    p2.my_print()
    

    输出:

    (1,2)
    (3,4)
    

    __str__

    __str__方法在对象被print函数打印时被调用,print输出__str__方法返回的字符串。

    案例:

    上面案例中Point类里的my_print方法可以去掉,定义一个__str__方法

    class Point:
        """
        表示平面坐标系中的一个点
        """
        name = '点'
        
        def __init__(self, x, y):
            self.x = x
            self.y = y
        
        def __str__(self):
            return '({},{})'.format(self.x, self.y)
    
        def distance(self, p2):
            return ((self.x-p2.x)**2 + (self.y-p2.y)**2)**0.5
        
        @classmethod
        def base_point(cls):
            return cls(0,0)
    p = Point(2,2)
    print(p)
    

    输出:

    (2,2)
    

    更多的特殊方法详见官方文档

    建议初学者,暂时学习这两个方法就够了。

    静态方法

    在类中通过装饰器staticmethod定义静态方法。

    静态方法不会接收隐式的第一个参数,它和普通的函数一样,只是被封装到类中。

    通过类和对象都可以调用。

    案例:

    在Point类中定义一个静态方法,用来计算两个数的和。

    class Point:
        """
        表示平面坐标系中的一个点
        """
        name = '点'
        
        def __init__(self, x, y):
            self.x = x
            self.y = y
        
        def __str__(self):
            return '({},{})'.format(self.x, self.y)
    
        def distance(self, p2):
            return ((self.x-p2.x)**2 + (self.y-p2.y)**2)**0.5
        
        @classmethod
        def base_point(cls):
            return cls(0,0)
        
        @staticmethod
        def sum(x,y):
            return x+y
    Point.sum(1,2)
    
    p = Point(1,2)
    p.sum(3,4)
    

    输出:

    3
    7
    

    总结:

    当某个函数和对象相关时,这个函数就可以定义为对象方法。

    当某个函数和类相关时,这个函数就可以定义为类方法。

    某个函数跟类和对象都不相关,但是又想通过类和对象去调用时,就可以定义为静态方法。

  • 相关阅读:
    eclipse rcp 获取工程项目路径
    Eclipse RCP中添加第三方jar包的办法
    eclipse content assist 代码提示功能失效解决办法
    lwuit更改字体大小
    lwuit调整滚动条灵敏度值
    AWTEvent
    IE7 IE6去掉关闭提示框的解决方案
    jQuery多库共存最优解决方案
    电子商务网站 数据库产品表设计方案
    javascript操作cookie
  • 原文地址:https://www.cnblogs.com/superwuchaofan/p/16635751.html
Copyright © 2020-2023  润新知