classmethod和staticmethod

  • 两个装饰器

    • classmethod : 被装饰的方法会成为一个静态方法

      • classmethod 什么时候用?

        1. 定义了一个方法,默认传self,但是这个self没有被用到
        2. 并且你在这个方法里用到了当前的类名,或者你准备使用这个类的内存空间中的名字的时候
      • 定义:

        • 装饰器怎么加

        • 参数怎么改

          class Goodds:
              __dicount = 0.8
          
              def __init__(self):
                  self.__Price = 5
                  self.price = self.__Price * self.__dicount
          
              @classmethod
              def change_discount(cls, new_discount):
                  cls.__dicount = new_discount
          
      • 用法:

        • 调用方法

          class Goodds:
              __dicount = 0.8
          
              def __init__(self):
                  self.__Price = 5
                  self.price = self.__Price * self.__dicount
          
              @classmethod
              def change_discount(cls, new_discount):
                  cls.__dicount = new_discount
          # 类方法可以通过类名调用
          Goodds.change_discount(0.6)
          apple = Goodds()
          print(apple.price)
          # 类方法可以通过对象名调用
          apple.change_discount(0.5)
          apple2 = Goodds()
          print(apple2.price)
          
          # import time
          # class Date:
          #     def __init__(self, year, month, day):
          #         self.year = year
          #         self.month = month
          #         self.day = day
          # 
          #     @classmethod
          #     def today(cls):
          #         struct_t = time.localtime()
          #         date = cls(struct_t.tm_year, struct_t.tm_mon, struct_t.tm_mday)
          #         return date
          # 
          # 
          # date_obj = Date.today()
          # print(date_obj.year)
          # print(date_obj.month)
          # print(date_obj.day)
          # # 2019
          # # 6
          # # 5
          
          
      • staticmethod : 被装饰的方法会成为一个静态方法

        • 用在:

          帮助我们把一个普通的函数挪到类中来直接使用,制造静态方法用的

        • 定义:

          class User:
          #     @staticmethod
          #     def login(a, b):
          #         print("登陆逻辑", a, b)
          #         # 在函数的内部既不会用到self变量,也不会用到cls类
          # 本身是一个普通的函数,被挪到类的内部执行,那么直接给这个函数添加@staticmethod装饰器就可以了
          
        • 调用方法:

          # class User:
          #     @staticmethod
          #     def login(a, b):
          #         print("登陆逻辑", a, b)
          #         # 在函数的内部既不会用到self变量,也不会用到cls类
          #
          # obj = User()
          # User.login(1, 2)
          # obj.login(3, 4)
          
          class A:
              country = '中国'
              def func(self):
                  print(self.__dict__)
          
              @classmethod
              def clas_func(cls):
                  print(cls)
          
              @staticmethod
              def stat_func():
                  print("普通函数")
          
              @property
              def name(self):
                  return 'wahah'
              
          # 能定义到类中的内容
          # 静态变量 是个所有的对象共享的变量  有对象类调用 但是不能重新赋值
          # 绑定方法 是个自带self参数的函数    由对象调用
          # 类方法   是个自带cls参数的函数     由对象类调用
          # 静态方法 是个啥都不带的普通函数    由对象类调用
          # property属性 是个伪装成属性的方法  由对象调用 但不加括号
          
  • 一些内置的魔术方法

    • ___new___
      class A:
          def __new__(cls, *args, **kwargs):
              o = object.__new__(cls)
              print("执行new", o)
              return o
      
          def __init__(self):
              print('执行initt', self)
      
      A()
      # 执行new <__main__.A object at 0x0000002F1E569048>
      # 执行initt <__main__.A object at 0x0000002F1E569048>
      
      # 实例化的时候,
      # 先创建一块对象的空间,有个指针能指向类 --》 __new__
      # 调用init--> __init__
      
      # 设计模式 -- 单例模式
      # 一个类,从头到尾只会创建一次self的空间
      
      class Baby:
          __instance = None
          def __new__(cls, *args, **kwargs):
              if cls.__instance is None:
                  # cls.__instance = super().__new__(cls)
                  cls.__instance = object.__new__(cls)
              return cls.__instance
          def __init__(self, cloth, pants):
              self.cloth = cloth
              self.pants = pants
      
      b1 = Baby('红毛衣', '绿裤子')
      print(b1.cloth)
      b2 = Baby('白衬衫', '黑裤子')
      print(b1.cloth)
      print(b2.cloth)
      
      # 单例模式2.0:
      class Baby:
          def __init__(self, cloth, pants):
              self.cloth = cloth
              self.pants = pants
      b1 = Baby('红上衣', '绿裤子')
      # 通过模块引用的方式
      # from 单例模式 import b1
      # from 单例模式 import b1
      
      
    • __cal__
      """ Call self as a function. """
      # class A:
      #     pass
      #
      # obj = A()
      # print(callable(obj))
      # False
      
      class A:
          def __call__(self, *args, **kwargs):
              print('___', args)
      obj = A()
      print(callable(obj))
      obj()
      # True
      # ___ ()
      
    • __len__
      
      class Cls:
          def __init__(self, name):
              self.name = name
              self.student = []
          def len(self):
              return len(self.student)
          def __len__(self):
              return len(self.student)
      
      py22 = Cls('py22')
      py22.student.append('abc')
      py22.student.append('123')
      py22.student.append('qaz')
      print(len(py22))
      
      
      class Pow:
          def __init__(self, n):
              self.n = n
          def __pow2__(self):
              return self.n ** 2
      
      def pow2(obj):
          return obj.__pow2__()
      
      obj = Pow(10)
      print(pow2(obj))
      
    • __str__
      class Course:
      #     def __init__(self, name, price, period):
      #         self.name = name
      #         self.price = price
      #         self.period = period
      # 
      #     def __str__(self):
      #         return self.name
      # 
      # python = Course('python', 21800, '6 month')
      # linux = Course('linux', 19800, '5 month')
      # mysql = Course('mysql', 12800, '3 month')
      # go = Course('go', 15800, '4 month')
      # print(go)
      # # go
      
      class cls:
          def __init__(self):
              self.student = []
          def append(self, name):
              self.student.append(name)
          def __str__(self):
              return str(self.student)
      py22= cls()
      py22.append('大壮')
      print("我们py22班 %s" %py22)
      print(py22)
      py22.append('小状')
      print(py22)
      # 在打印一个对象的时候 调用__str__方法
      # 在%s拼接一个对象的时候 调用__str__方法
      # 在str一个对象的时候 调用__str__方法
      
    • __repr__
      py22 = clas()
      py22.append('大壮')
      print(py22)
      print(str(py22))
      print('我们py22班 %s'%py22)
      print('我们py22班 %r'%py22)
      print(repr(py22))
      # 当我们打印一个对象 用%s进行字符串拼接 或者str(对象)总是调用这个对象的__str__方法
      # 如果找不到__str__,就调用__repr__方法
      # __repr__不仅是__str__的替代品,还有自己的功能
      # 用%r进行字符串拼接 或者用repr(对象)的时候总是调用这个对象的__repr__方法
      
      
原文地址:https://www.cnblogs.com/zh-lei/p/10995191.html