类方法和静态方法

类方法和静态方法

一、类方法

  • 类方法定义:

    • 类方法:是由类来调用的方法,不是普通的构造方法,类方法约定俗称第一个参数是cls
      表示的是class,python把class的命名空间(内存地址)传递给类方法

         class A(object):
            def func(self):
                print(self)
      
        a1 = A()
        a1.func()
        
        
        # 方法打印self,结果是本类在电脑中的内存地址,这种是普通的构造方法
        
        class B(object):
            @classmethod
            # 添加类方法的装饰器
            def func(cls):
                # 参数固定是cls,表示的是class
                print(cls)
        
            
        b1 = B()
        b1.func()
        B.func()
        '''
        类方法:由类来调用的方法,不是由实例对象调用的方法。类方法需要在构造方法
        上添加@classmethod装饰器,并且类方法的第一个参数约定俗成为cls。实际上是
        python把类的命名空间(内存地址)传递给类方法
        '''      
      
    • 把普通的构造方法转变成类方法需要在构造方法上添加@classmethod装饰器

    • 类方法不需要对象参与,当需要对类中的静态方法改变的时候需要用到类方法,用cls调用,不用类名

    Note
    需要注意的是,普通方法是不推荐直接用类名直接调用类中的方法的,正常情况下都是实例化对象调用,但是如果使用了类方法装饰器
    把普通的方法转变成类方法后,则可以直接使用类名.方法名来调用。参数cls等同与本类,可以直接使用cls调用方法和静态字段,可
    以在类方法中修改静态字段,但是调用的类中的方法只能输出到对应的内存地址,不能获取到返回值。

        '''实例一'''   
        class B(object):
            name = 'alex'
            __age = 100
            count = 1
            @classmethod
            # 添加类方法的装饰器
            def func(cls):
                # 参数固定是cls,表示的是class  
                cls.__age = cls.__age + 20                              
                return '%s的年龄为%s,第%s次返回' % (cls.name, cls.__age, cls.count + 1)
                # 这里可以直接使用cls来调用类中的变量、属性和方法
               
           b1 = B()
           b1.func()
           print(B.func()) 
           
           '''实例二'''
           class Person(object):
           __age = 100
           country = '中国'
           province = '北京'
           
           def __init__(self, name, height, weight):
               self.name = name
               self.height = height
               self.__weight = weight
           
           @property
           def bmi(self):
               bmi = self.__weight / self.height ** 2
               return bmi
           
           @bmi.setter
           def bmi(self, h1):
               self.height = h1
           
           # bmi = self.__weight / self.__height ** 2
           # return bmi
           
           @bmi.deleter
           def bmi(self):
               del self.height
               del self.__weight
           
           def get_name(self):
               return self.name
           
           @classmethod
           def message(cls, province):
               cls.province = province
               return cls.__age, cls.province, cls.country, cls.bmi, cls.get_name
           # 类方法中的第一个参数是cls,后边是其他的参数,和普通的方法用法基本一致。
           # 类方法只能通过cls来调用和修改类中的静态字段,不能调用属性,也可以调用类中的方法
           # 但是/输出的结果是方法的内存地址,如果是伪造属性,输出的是属性的内存地址
       
           p1 = Person('刘洋', 1.7, 95)
           print(p1.bmi)
           p1.height = 2.23
           print(p1.bmi)
           print(Person.message('河南'))
    
   
- <font color='red'>类的静态方法可以被继承,可以直接使用子类调用父类中的静态方法</font>

    ```python 
     class A(object):
        __country = '中国'
        province = '北京'
        
        def __init__(self, name, age, gender):
            self.name = name
            self.__age = age
            self.gender = gender
        
        @classmethod
        def func(cls):
            # cls:哪个类调用就显示哪个类的类空间
            return cls.__country, cls, cls.province
    
        class B(A):
            province = '河南'
        
        
        print(B.func())
        # B类继承自A类,那么B类也就继承类A类中的类方法,类方法中的cls此时表示的就是B类,输出B类的内存地址
        # 子类不能继承父类的私有方法、私有属性和私有类变量,其他的都可以继承
    ```

 - 实现子类调用父类方法从而调用子类中的静态字段的方式
    - 方式一:通过类方法,传递cls来实现调用
    - 方法二:通过普通方法,子类中没有,父类中有,通过self来调用
    
        ```python 
         class A(object):
            __country = '中国'
            province = '北京'
            
            def __init__(self, name, age, gender):
                self.name = name
                self.__age = age
                self.gender = gender 
      
            # 方式一
            @classmethod
            def func(cls, province):
                # cls:哪个类调用就显示哪个类的类空间
                cls.province = province
                # 类方法可以访问并修改类中的静态字段
                return cls.__country, cls, cls.province
             
            # 方式二 
            def func1(self):
                print(self.province)
                self.province = '广东'
                print(self.province)
                # 普通方法也可以通过父类调用子类中的字段
                # 普通方法只能查询类中的静态字段
        
            
        class B(A):
            province = '河南'
        
        
        print(B.func('上海'))
        # B类继承自A类,那么B类也就继承类A类中的类方法,类方法中的cls此时表示的就是B类,输出B类的内存地址
        # 子类不能继承父类的私有方法、私有属性和私有类变量,其他的都可以继承
        b1 = B('里流', 12, '男')
        b1.func1()
        print(B.province)  
        
        '''
        结果是:上海、广东、上海
        '''

        ```  
      > **Note**
      需要注意的是:类方法和普通方法都可以实现父类方法调用子类静态字段的目的,但是区别在于:
      <font color='red'>类方法中可以直接修改子类中的静态字段值,而普通方法不能修改静态字段值</font>。
 
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   
####二、静态方法       
- 静态方法存在于类中,需要用到@staticmethod装饰器
- 静态方法可以不传递任何的参数,也可以传递参数
- 静态方法等同于在类中创建了一个单独的函数
- 静态方法的好处
    - 代码块,清晰明了
    - 增加代码的复用性

    ```python 
  
        class C:
          __age = 100
        
          @staticmethod
          def login(username, password):
              if username == '李镇' and password == '12345':
                  print('登陆成功')
              else:
                  print('登陆失败')
                
        c1 = C()
        c1.login('李镇', '123456') 
          
       # 输出结果:登陆失败
    ```
posted @ 2020-02-04 14:17  大道至诚  阅读(517)  评论(0编辑  收藏  举报