技术分享图片
人生三从境界:昨夜西风凋碧树,独上高楼,望尽天涯路。 衣带渐宽终不悔,为伊消得人憔悴。 众里寻他千百度,蓦然回首,那人却在灯火阑珊处。

Python_面向对象

一、内容回顾

  成员

  class Person:

    def __init__(self, name, num, gender, birthday):

      # 成员变量

      self.name = name 

      self.num = num

      self.gender = gender

      self.birthday = birthday

      # 对象来访问(成员方法)(实例方法)

      def eat(self,name):

        print("%s吃东西"%self.name)

      

   ### 成员:在类定义的变量和方法都被称为成员

      变量:  

        1、成员变量(实例变量)、字段

        2、类变量(静态变量) 

      方法:

        1、成员(实例)方法,加了self的,调用的时候,必须用对象去访问

        2、类方法   @classmethod def clsMethod(cls) ## 类方法:第一个参数传递的是类名

        3、静态方法,当你的方法不需要传递当前类的对象。语法规则:在方法上面加@staticmethod

       ------>>>>>说一说,静态方法、类方法和实例方法的区别

      属性:

        用方法描述我们的属性信息

        @property ## 表示当前方法是一个属性, 方法的返回就是这个属性的值,不用加括号(就是属性),直接访问属性,实际上访问

        的是xxx()方法,返回值就是属性值 ## 方法只能有一个参数,就是self,并且要return 

        注意:

          1、@property 改变一个方法称为属性

          2、这个方法只能有一个参数,self

          3、必须要有return

 

    私有:

       只能在自己类中执行,__方法,__属性,__

 

 二、类与类之间关系

  1、依赖关系(紧密程度最低)(大象装冰箱)

    最轻的一种关系

    在方法中引入领一个类的对象

  2、关联关系

    类与类之间的关系是比较紧密的。

  3、组合关系

  4、聚合关系

  5、继承关系、实现关系

    self :当前执行这个方法的对象

三、类名和对象是否可以作为key

  # 对可哈希,内部是否哈希算法 __hash__

  1、 class Foo(object): ## 所有的类都会默认继承obj

    def __init__(self):

      pass

    def func(self):

      pass

    __hash__ = None

   dic = {}

   dic[Foo] = '12344'  ## 类名是可哈希的

   dic[Foo()] = 'hello'  ## TypeError : unhashable type:'Foo'  类中是否包含__hash__

   print(dic)

   ## list dic set 内部中__hash__ = None , 是不可哈希的

  eg: 

     self 到底是谁?

      ## self 当前访问xx方法的那个对象

四、类中的特殊成员

     什么是特殊成员?__init__() 就是一个特殊的成员,带双下划先的那一坨,这些方法

   在特殊的场景的时候会被自动的执行。

     1、类名()  将 执行 __init__() 构造方法 

     2、对象()  == >> obj()  会默认执行  __call__ ## python 特有

     3、对象[]  ==>> obj[xxxx ]    从对象中获取数据 默认执行 __getitem__()

     4、对象[] = xxx  == >> 默认执行 _setitem__()

        5、del obj[key]  默认执行_-delitem__()

     6、打印对象的时候 会自动执行 __str__()

     7、with 对象 as 变量 会自动执行 __enter__ 和 __exit__()

   

    __new__():

        1、加载类

        2、开辟内存空间   

            (开辟方法)

             def __new__(cls,*args,**kwargs):

                return object.__new__(cls)  ## 这句话才是创建对象,其他都是初始化对象

        3、初始化这一块内存__init __

  

 五、issubclass 、 type 、isinstance

    issubclass  判断xxxx类是否是xxx类的子类  

    type 给出xxx的数据类型

    isinstance 判断对象是否是XXX家族体系的内容,往上找

    

    区分方法和函数:

      在外面定义的函数一定是函数

      实例方法:   对象.方法   方法       类名.方法   函数

            静态方法: 都是函数   @staticmethod

            类方法:     都是方法  @classmethod

    ## 引入两个模块

      from types import FunctionType, MethodType

      def haha(arg):

      print(isinstance(arg, FunctionType))      

      print(isinstance(arg, MethodType))         

      haha(XXX.class_method)

      haha()

六、反射(重点)

  getattr(obj,"xxx")         ##  从xxx对象或者模块中找xxxx()的功能(字符串)

  hasattr(obj,"xxx")        ##  判断xxx对象或者模块存才"xxx"

  setattr(obj,xxx1,xxx2) ##  修改 仅限于内存  动态的设置给对象属性和值

  delattr(obj,"xxx")         ##  删除 仅限于内存

  callabel(func) ## 判断这个鬼东西时是否可以被调用

  if hasattr(obj, "xxx"):

    func = getattr(obj, "xxx")

    if callable(func):

      func()

    else:

      print(func())

  else:

    print("None")

七、面向对象的反射

  def Person:

    def __init__(self,name):

      self.name = name 

    def chi(self):

      print("chidongxi")

   p = Person("你好")

     # p.chi()

 

   chi = hasattr(p,"chi")

   chi()  # ??

 

   val = input("请输入:")

   if hasattr(p, val):

    attr = getattr(p, val)

    attr()

八、约束和异常处理

  

  (1)异常处理(处理、抛出异常、自定义异常)

    1、产生异常:raise 异常类(),抛出异常

    2、处理异常:

      try :

        xxx  ## 尝试执行的代码

      except 异常类 as 变量: ## 出现错误的时候,捕获到异常

        xxxx ## 处理异常

    3、自定义异常

        继承Exception

    4、堆栈信息

      import traceback

      traceback.format_exc()  ## 获取堆栈信息

  (2)约束(难)

      一、通过抛出异常(简单,才是真正PYTHON中写法)

        约束是对子类进行的约束(进行修改,统一)

        在父类中给出一个方法。这个方法中什么都不写。就抛出异常,NotImplementError()

        在子类中把上述的方法进行重写

        重写:子类重新定义父类中的方法。

      二、抽象类和抽象方法(java,C#)

        from abc improt ABCMeta, abstractmethod

        抽象方法:抽象方法不用给出方法体,写个pass

        抽象类:

            语法:类(metaclass = ABCMeta)

            概念:如果类中包含了抽象方法,这个类一定是抽象类

            特点:  抽象类一般不创建对象.

               抽象类中可以存在正常方法

        可以约束子类必须实现抽象方法

                      

      抽象(百度贴吧)

      class Base:

        def login(self):

          raise NotImplementedError("没有实现login方法")  ## 专业的写法

      ## 张三

      class Normal:

        def login(self):

          print("普通人登录")

      ## 李四

      class Member:

        def denglu(self):

          print("吧务登录")

      ## 王五

      class Admin:

        def login(self):

          print("管理员登录")

 

      def login(obj):

        print("产生验证码")

        obj.login()

        print("进入主页")

      #场景

      n = Normal()

      m  = Member()

      a = Admin()

      login(n)

      login(m)   

      login(a)

      ## 重写  :子类对父类提供的方法不满意,重新去定义这个方法

      from abc improt ABCMeta, abstractmethod(抽象方法)

      class Animal(metaclass = ABCMeta): ## 在父类中写出metaclass = xxx 抽象类

        @abstractmethod  ## 抽象方法

        def chi(self):  ## 抽象的概念, 

          pass

        ##def dong(self):

          ##    print("123")

      class Cat(Animal):  ## 子类必须实现父类中的抽象方法

        def chi(self): ## 具体的表现

          pritn("猫爱吃鱼")

    

          

 九、MD5加密

    MD5加密:不可逆##  (网站上的解密md5都是有(以前别人数据)查询)

     引入模块 hashlib

    (1) imoprt hashlib

      ## 1.创建一个md5加密

      obj = hashlib.md5(b"sdf1asd45f6sadfg") ## 加盐

      ## 2.把要加密的内容给md5

      obj.updata("123",encode("utf-8"))  ## 必须是字节

      ## 3.获取密文

      val = obj.hexdigest()  

      print(val)

    

    def my_md5(val):

      obj = hashlib.md5(b"asdf2sd1f")

      obj.updata(val,encode = "utf8")

      val = obj.hexdigest()

      return val

 

    ## 注册的时候, 用md5进行加密, 存储的是加密后的密文

      username = input("请输入你的用户名")

      password  = input("请输入你的密码")

      cun = my_md5(password)

      print(cun)

 

    ## 用户登录

           if username == "xxx" and y_md5(password) == "xxxxxxxxxxxxxx":

        print("登录成功")

      else:

        print("登录失败")

十、日志处理(重要、简单)

  引入logging模块

  logging.basicConfig(filename= 'xxx.log',

            fromat = "%(name)s-%(levelname)s-%(module)s:%(message)s",

            datefmt = "%Y-%m-%d %H :%M:%S",

            level = 30) ## level 设置级别,当你的信息的级别>=level 的时候才会写入日志文件,默认30

  ## 写日志

  logging.critical("xxxx")

  logging.error("xxxx")

  logging.info("xxxxx")

  logging.debug("xxxx")

  logging.log(int,"xxxx")

  非必现bug

  import traceback

  for i in range(20):

    try:

      if i % 3 == 0:

        raise FileNotFoundError("xxxxx")

      elif i % 3 == 1:

        raise StopIteration()

      elif i % 3 == 2:

        rause KeyError()

    except FileNotFoundError as e:

        val = traceback.format_exc()

        logging.error(val)

    

    except StopIteration as e:

        val = traceback.format_exc()

        logging.error(val)

    

    except KeyError as e:

        val = traceback.format_exc()

        logging.error(val)

    

## 多文件日志处理

    #创建一个操作日志的对象logger(依赖FileHandler)
  filehandler=logging.FilelHandler('11.1og','a',encoding='utf-s')
  filehandler.setFormatter(logging.Formatter(fmt="%(asctime)s-%(name)s-%(levelname)s-%(module)s:%(message)s"))
  logger1=logging.Logger('s1',level=logging.ERROR)
  logger1.addHandler(file_handler)
  logger1.error("我是A系统")

  

  #在创建一众操作旦志的对象loggar(依赖Filellandler)file_handler2=logging.FileHandler('12.1og','a',encoding='utf-8')
  file handler2.setFormatter(logging.Focmatte'(fmt="%(asctim)s-%(name)s-%(levelname)s-%(module)s:%(message)s"))
  logger2=logging.Logger('B',level=40)

  logger2.addHandler(file_handler2)
  logger2.error(”我是B系统")

 

十一、内容回顾

  1、异常处埋
    raise:抛出异常.
    try:
      可能会出现错误的代码
    except 异常类ase:
      异常的处理
    except 异常类ase:
      异常的处理
    except 异常类as e:

      异常的处理
    except 异常类as e:

      异常的处理

    else:
      如果上面的代码没有错误,执行这里的代码
    finally:

      收尾
    自定义异常:随便写个类.继承Exception

  

  2.约束
    父类和子类.
      在父类中声明方法.要求子类必须重写它
      1.抛出异常.raise NotImplementError
      2.抽象类和抽象方法
        from abc import ABCMeta,abstractmethod在父类声明的时候,metaclass=ABCMeta

        方法上面加@abstractmethod

        子类必须重写这个抽象方法.
        接口:定义方法和约束子类

  3.MD5
    1.引入模块
        import hashlib
    2.创建md5对象(实例化)
      obj=hashlib.md5(b"盐")
    3.把加密的内容交给md5
      obj.update(bytes)
    4.获取密文
      obj.hexdigest()

  4.日志
    logging模块

        basicConfig filename format datefmt level级别。
    CRITICAL   50
    ERROR      40
    WARNING  30
    INFO     20
    DEBUG      10
    NOTEST          0

 

 十二、新式类和经典类的MRO(方法路径顺序)

    class Base1:

      def func(self):

        super().func()#Base2里的func

        print("娃哈哈")

    class Base2:

      def func(self):.
        print("雪碧")

    class Foo(Basel,Base2):#*Foo,Basel,Base2
      pass

    f=Foo()
    f.func()

  MRO(method resolution Order)方法路径顺序.
    python2
      1.使用经典类(写继承关系的时候.基类不继承object) , 所使用的是MOR是深度优先遍历
      2.新式类(继承关系的根.是object)
    python3
      只有新式类

      新式类的MRO,C3(重点,难点)

      新式类中摒弃了(部分).C3算法如果你的继承关系中没有菱形继承(深度优先就够)。

      如果有菱形:使用C3算法来计算MRO假设C3算法.是L(x)=x的继承关系号先拆分。拆到你能看出结果为止

      反复进行merge(元组,元组。。。。、。。)运算

      !!!摘头,头和尾在对比,如果下一个尾没有这个头,头就出现,如果出现,跳过该元组,继续下一个元组的头,反复,在回到上一个元组持续进行。 

      如果是简单的菱形继承,把头干掉。使用深部遍历,最后是头。

      如果是复杂的菱形继承,需要C3算法,  xxx.__mro__(),找到每个类的继承关系,然后拆分,再合并。

      第一件事,先画图,看有没有菱形继承

      

      

 

十三、常用模块

  (1)random

    ## 小数

     random.random() ## 0-1小数

     random.uniform(1,3) ## 1-3之间的小数

    ## 整数

     random.randint(1,36) ## 【1-36】随机数

     random.randrange(1,5,3) ## [1,5) 步长是3

    ##

     random.choice(["xxx", "xxx", "xxxx"])  ## 随机选一个

     random.sample(list[range(1,37)],  3) ##随机选3个 

     lst = [131,5,21,54,2,34,465,12]

     random.shuffle(lst) # #洗牌

  (2)Queue 队列  stack 栈 

  (3)collections

    1、Counter

    2、queue  # 双端队列  d = queue()

    3、namedtuple ## 定义一个简单的类

    4、defaultdict

  (4)time

    time.time()  ## 获取时间戳

    time.strftime("%Y-%m-%d") ## 时间格式, 格式化时间

    time.localtime() # 结构化时间 ,用来计算的

  (5)os

    os.makedirs("a/b/c")    ## 创建多级目录

    os.removedirs("a/b/c") ## 删除多级目录(不能有文件,对文件的一种保护)

    os.listdir("xxx/")    ## 列出指定文件目录下的所有文件和子目录, 包括隐藏文件,并以列表方式打印

    os.remove()    ## 删除一个文件

    os.stat()     ## 获取文件

    os.system(“dir”)          ## 直接执行shell 命令

    os.popen("dir").read() ## 执行命令,返回结果

   ##os.path

     os.path.split("xxx/xxx/xxx.xxx") ## 拆开 

     os.path.dirname(path) 

     os.path.exists(path)  ## 判断路劲是否存在

     os.path.join(path1,path2)  ## 合并

  ## 特殊属性

    os.sep           ## 输出操作系统特点的路劲分隔符 

    os.linesep     ##  输出当前平台使用的行终止符 win "\r\n"  linux "\n"

    os.pathsep    ## 输出分割文件路劲的字符串

    os.name        ## win - >  nt,NT,     linux- > "posix"

  (6)sys 模块

     所有和python解释器相关的都在sys模块;

    sys.argv  命令行参数LIST,第一个元素是程序本身路径

    sys.version  获取Python解释程序的版本信息

    sys.exit(0)  退出程序,正常退出是exit(0) ,错误退出sys.exit(1)

    sys.path   返回模块的搜索路径,初始化时使用PYTHON环境变量的值

 十四、序列化

   1)pickle

    ## dumps  把对象转化成BYTES  (序列化)

    ## loads    bytes转化成对象   (反序列化)

    ## dump   把对象转化成bytes并写入文件

    ## load     把文件中的bytes读取,转化成对象

  2)shelve

    ##提供python持久化操作

    ## open("文件")

    f  = shelve("xxxx")  ## 相当于 f = {}

    f["xxxx"]  =  "xxx"

    f.close()

  3)json

   import json

   dic = {"a":"xxx","b":"xxxxx","c","xxxxx"}  ## 如果你的的k或者v超出ascii范畴,就会显示成\uxxxx

      s = json.dumps(dic,ensure_ascii = False)

   print(repr(s), type(s) )  ## 类型是str

   ## 把字符串解析成字典

    dic = json.loads(s) 

    print(dic, type(dic) )  ## 类型是dict

    

 

    

    ## 写入的时候

      1)循环

      2)用dumps把字典转化成字符串, 然后手动在后面加一个\n

      3)写出

    ## 读取的时候

      1)for line in f:

      2)  strip() 去掉空白

      3)loads()变成字典

   4)configparser模块

    该模块适用于配置文件的格式与windows ini 文件类似。

    conf = configparser.ConfigParser()

    conf["DEFAULT"] = {

        "session-time-out" :30,

        "user-alive":50  

      }

    conf["189-DB"] = {

          "ip":"189.135.1.1",

          "port":"3306"

      }

    f = open("xxx.ini", mode = "w")

    conf.write(f) ## 把文件扔进去

    ## 读取内容

    conf  = configparser.ConParser()

    conf.read("xxx.ini")

    conf.sections() ## 获取到章节

      ## 可以想字典一样操作

   

 

 

 

 

 

 

    

 

 

 

 

 

 

 

 

 

    

     

   

       

  

  

  

  

 

  

  

  

  

   

 

 

      

        

  

        

            

 

posted @ 2019-10-26 20:32  山海郡  阅读(209)  评论(0编辑  收藏  举报