zoukankan      html  css  js  c++  java
  • Python

    传送门

    1. https://github.com/jackfrued/Python-100-Days/blob/master/Day01-15/Day09/面向对象进阶.md#静态方法和类方法

    静态方法@staticmethod

    1. 记得在Fluent Python中大神讲过@staticmethod和普通的函数没什么两样;但是在以下的例子中可以看到,@staticmethod意义在于,这个静态方法和这个类是相关的(虽然这个类的实例对象能调用),但是一般这样设计是给类调用的。
    2. 例子: 我们定义一个“三角形”类,通过传入三条边长来构造三角形,并提供计算周长和面积的方法,但是传入的三条边长未必能构造出三角形对象,因此我们可以先写一个方法来验证三条边长是否可以构成三角形,**这个方法很显然就不是对象方法**,因为在调用这个方法时三角形对象尚未创建出来(因为都不知道三条边能不能构成三角形),所以**这个方法是属于三角形类而并不属于三角形对象的**。我们可以使用静态方法来解决这类问题,代码如下所示。
      
    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(t.perimeter())
            # 也可以通过给类发消息来调用对象方法但是要传入接收消息的对象作为参数
            # print(Triangle.perimeter(t))
            print(t.area())
            # print(Triangle.area(t))
        else:
            print('无法构成三角形.')
    
    
    if __name__ == '__main__':
        main()
    

    类方法@classmethod

    1. 和静态方法比较类似,Python还可以在类中定义类方法,类方法的第一个参数约定名(convention)为cls,它代表的是当前类相关的信息的对象(类本身也是一个对象,有的地方也称之为类的元数据对象),通过这个参数我们可以获取和类相关的信息并且可以创建出类的对象(在@classmethod修饰的函数中return cls()),代码如下所示。
    from time import time, localtime, sleep
    
    
    class Clock(object):
        """数字时钟"""
    
        def __init__(self, hour=0, minute=0, second=0):
            self._hour = hour
            self._minute = minute
            self._second = second
    
        @classmethod
        def now(cls):
            current_time = localtime(time())
            return cls(current_time.tm_hour, current_time.tm_min, current_time.tm_sec)
    
        def run(self):
            """走字"""
            self._second += 1
            if self._second == 60:
                self._second = 0
                self._minute += 1
                if self._minute == 60:
                    self._minute = 0
                    self._hour += 1
                    if self._hour == 24:
                        self._hour = 0
    
        def show(self):
            """显示时间"""
            return '%02d:%02d:%02d' % 
                   (self._hour, self._minute, self._second)
    
    
    def main():
        # 通过类方法创建对象并获取系统时间
        clock = Clock.now()
        while True:
            print(clock.show())
            sleep(1)
            clock.run()
    
    
    if __name__ == '__main__':
        main()
    

    @staticmethod 和 @classmethod

    class Demo():
    
        @classmethod
        def klassmeth(cls, *args):
            return args
    
        @staticmethod
        def statmeth(*args):
            return args
    
    # 不加cls,退化成@staticmethod
    print(Demo.klassmeth())     # ()
    print(Demo.klassmeth('spam'))     # ()
    
    print(Demo.klassmeth(Demo,))    # (<class '__main__.Demo'>,)
    print(Demo.klassmeth(Demo, 'spam'))     # (<class '__main__.Demo'>, 'spam')
    
    print(Demo.statmeth())  # ()
    print(Demo.statmeth('spam')) # ('spam',)
    
  • 相关阅读:
    文件上传长度限制
    js之图片放大
    Jquery中$与$.fn的区别
    取消svn和文件的关联
    Java——如何创建文件夹及文件,删除文件,文件夹
    SQL语法
    linux环境运行java项目并有外部引用jar
    Eclipse-与Centos远程调试
    Eclipse-远程调试
    使用java代码执行linux命令
  • 原文地址:https://www.cnblogs.com/allen2333/p/9219054.html
Copyright © 2011-2022 走看看