• 两个类的装饰器,内置的魔术方法


    类的装饰器

    classmethod

    1. 什么时候用?

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

    2. 怎么定义?

      1. 装饰器怎么加?

        在被装饰的方法前写@classmethod

      2. 参数怎么改?

        将self改成cls,并在方法里面需要用类名的地方一致写上cls

       
      1 # classmethod  被装饰的方法会成为一个静态方法
      2  # class Goods:
      3  #     __discount = 0.8
      4  #     def __init__(self):
      5  #         self.__price = 5
      6  #         self.price = self.__price * self.__discount
      7  #     @classmethod   # 把一个对象绑定的方法 修改成一个 类方法
      8  #     def change_discount(cls,new_discount):
      9  #         cls.__discount = new_discount
    3. 怎么用?

      类名或者对象名皆可调用

      1  # Goods.change_discount(0.6)   # 类方法可以通过类名调用
      2  # apple = Goods()
      3  # print(apple.price)
      4  # apple.change_discount(0.5)  # 类方法可以通过对象名调用
      5  # apple2 = Goods()
      6  # print(apple2.price)
    4. 为什么用?有什么好处?

      在方法中仍然可以引用类中的静态变量;可以不用实例化对象,就直接用类名在外部调用这个方法

    例子

     1  # import time
     2  # class Date:
     3  #     def __init__(self,year,month,day):
     4  #         self.year = year
     5  #         self.month = month
     6  #         self.day = day
     7  #     @classmethod
     8  #     def today(cls):
     9  #         struct_t = time.localtime()
    10  #         date = cls(struct_t.tm_year,struct_t.tm_mon,struct_t.tm_mday)
    11  #         return date
    12  #
    13  # date对象 = Date.today()
    14  # print(date对象.year)
    15  # print(date对象.month)
    16  # print(date对象.day)

    staticmethod

    1. 什么时候用

      本身是一个普通的函数,被移到类的内部执行,在方法内部既不会用到self变量,也不会用到cls变量

    2. 怎么定义

      在方法之前写上@staticmethod,别的不用改

      1  # class User:
      2  #     pass
      3  #     @staticmethod
      4  #     def login(a,b):      # 本身是一个普通的函数,被挪到类的内部执行,那么直接给这个函数添加@staticmethod装饰器就可以了
      5  #         print('登录的逻辑',a,b)
    3. 怎么用?由谁来调用

      对象和类都可以调用

      1  # obj = User()
      2  # User.login(1,2)
      3  # obj.login(3,4)

    能定义在类中的内容

    静态变量:是个所有的对象共享的变量 由对象类调用

    绑定方法:是个自带self参数的函数 由对象调用

    类方法:是个自带cls参数的函数 由对象类调用

    静态方法:是个啥都不带的普通函数 由对象类调用

    property属性:是个伪装成属性的方法 由对象调用 但不加括号

     
     1 class A:
     2      country = '中国'
     3      def func(self):
     4          print(self.__dict__)
     5      @classmethod
     6      def clas_func(cls):
     7          print(cls)
     8      @staticmethod
     9      def stat_func():
    10          print('普通函数')
    11      @property
    12      def name(self):
    13          return 'wahaha'

    一些内置的魔术方法

    __call__方法

    类中有__call__方法的话就可被调用

    对象()能不能运行就是callable判断的事

    1  class A:
    2      def __call__(self, *args, **kwargs):
    3          print('-------')
    4  # obj = A()
    5  # print(callable(obj))
    6  # obj()
    7  # Flask框架的源码
    8  # A()()    # 实例化对象在调用方法

    __len__方法

    len(对象)可不可用取决于这个类中有无__len__方法

     1  class Cls:
     2      def __init__(self,name):
     3          self.name = name
     4          self.students = []
     5      def __len__(self):
     6          return len(self.students)
     7  py22 = Cls('py22')
     8  py22.students.append('杜相玺')
     9  py22.students.append('庄博')
    10  py22.students.append('大壮')
    11  print(py22.__len__())
    12  print(len(py22))

    假如自己定义一个方法

     1 # class Pow:
     2 #     def __init__(self,n):
     3 #         self.n = n
     4 #     def __pow2__(self):
     5 #         return self.n ** 2
     6 
     7 # def pow2(obj):               # 这一步为了实现类似于len(list_1)的功能
     8 #     return obj.__pow2__()
     9 # obj = Pow(10)
    10 # print(obj.__pow2__())

    __str__方法和__repr__方法

    1. __str__方法:

      1. 在打印一个对象的时候 调用__str__方法

      2. 在%s拼接一个对象的时候 调用__str__方法

      3. 在str一个对象的时候 调用__str__方法

       1 # class clas:
       2 #     def __init__(self):
       3 #         self.student = []
       4 #     def append(self,name):
       5 #         self.student.append(name)
       6 #     def __str__(self):
       7 #         return str(self.student)
       8 #
       9 # py22 = clas()
      10 # py22.append('大壮')
      11 # print(py22)
      12 # print(str(py22))
      13 # print('我们py22班 %s'%py22)
      14 # print(py22)
      15 # py22.append('大壮')
      16 # print(py22)
    2. __repr__方法

      1. 如果找不到__str__,就调用__repr__方法

      2. 用%r进行字符串拼接

      3. 用repr(对象)的时候

       1 # class clas:
       2 #     def __init__(self):
       3 #         self.student = []
       4 #     def append(self,name):
       5 #         self.student.append(name)
       6 #     def __repr__(self):
       7 #         return str(self.student)
       8 #     def __str__(self):
       9 #         return 'aaa'
      10 #
      11 # py22 = clas()
      12 # py22.append('大壮')
      13 # print(py22)
      14 # print(str(py22))
      15 # print('我们py22班 %s'%py22)
      16 # print('我们py22班 %r'%py22)
      17 # print(repr(py22))

    __new__方法***

    __new__方法是一种构造方法,其作用是在实例化的时候创建一块对象的空间,有一个指针可以指向类。其顺序在__init__之前

    1 # class A:
    2 #     def __new__(cls, *args, **kwargs):   # 构造方法
    3 #         # o = super().__new__(cls)  #方法一
    4 #         o = object.__new__(cls)     #方法二   两种方法皆可
    5 #         print('执行new',o)
    6 #         return o
    7 #     def __init__(self):
    8 #         print('执行init',self)
    9 # A()

    注意:在这个例子中self与o打印出来的结果一致,因为先调用__new__实例化以后会自动把这个实例传给self

    设计模式—单例

    总共有五种实现方法

    方法一***(面试用):

     1 class Baby:
     2     __instance = None
     3     def __new__(cls, *args, **kwargs):
     4         if cls.__instance is None:
     5             cls.__instance = super().__new__(cls)
     6         return cls.__instance
     7     def __init__(self,cloth,pants):
     8         self.cloth = cloth
     9         self.pants = pants
    10 b1 = Baby('红毛衣','绿皮裤')
    11 print(b1.cloth)
    12 b2 = Baby('白衬衫','黑豹纹')
    13 print(b1.cloth)
    14 print(b2.cloth)

    方法二(平时用,简单方便):

    1 # 在另一个模块中  单例.py
    2 class Baby:
    3     def __init__(self,cloth,pants):
    4         self.cloth = cloth
    5         self.pants = pants
    6 
    7 baby = Baby('红上衣','绿裤子')
    1 # 在当前运行脚本下
    2 from 单例 import baby
    3 print(baby)
    4 # 一个模块不会被重复导入,所以导入一次每次都是同一个地址
  • 相关阅读:
    Kernel panic
    elasticsearch5.4 安装篇
    nginx 切割日志文件
    dl 320e gen8 v2 安装2008 r2 系统
    idea开发配置
    红黑树
    二叉搜索树
    Object
    nginx
    docker
  • 原文地址:https://www.cnblogs.com/zhangxiangning/p/10268519.html
Copyright © 2020-2023  润新知