zoukankan      html  css  js  c++  java
  • day07 类

    一、目录

    1.模块

    2.包

    3.isinstance issubclass type

    4.方法和函数

    5.反射

    6.约束

    7.继承

    8.特殊成员

    9.异常处理

    补充知识点

    10.hashlib模块

    11.logging日志模块

    二、内容

    一.模块

     模块的概述:模块本质上就是一个py文件,一行一行代码多了会通过函数来封装,函数多了以后会通过class类来封装,class类多了就通过一个个py文件,也就是我们

    所说的模块。导入模块的方式:import py文件  或者 from py文件 import py文件里面的具体xxx 

    导入模块的工作原理:

    1.判断内存中是否有master   ps:以master文件为例
    2.如果有,直接拿过来使用
    3.如果没有,会开辟一个内存空间
    4.在该内存空间中执行模块中的代码
    5. 默认把名称空间的名字引入进来

    导入模块的规则:
    规则
    1.导入模块写入py文件的最开始
    2.顺序
    内置模块》第三方模块》自己定义的模块

    __name__ 在当前文件作为启动文件的时候"__main__"  
    当py文件作为模块被导入的时候是文件自己的名字

    python程序的模块搜索路径 通过sys.path查看
    sys.modules 当前已经导入的模块
    sys.path 模块的搜索路径
    sys.path.append ps:可添加xx路径到path路径下

    二.包

      包的概述: 包下面存放的是一个个py文件,好处:结构清晰易于管理

    包的导入方式:from 路径 import 包    ps: import 不能直接加点, 点在这里代表的是xx下的xx。import 后直接写目录默认会导入__init__.py文件。导入包的path以包的启动文件为准。导入包有 两种方式相对导入和绝对导入,相对导入容易出问题,相对导入在导入的那个文件里面执行代码会报错,原因是不能出当前path文件,所以一般推荐绝对导入。

    三.isinstance issubclass type

    isinstance:查看某数据的类型

    insubclass:查看xx 是否是xx的子类

    type: 查看数据的具体类型

    class Animal:
    def run(self):
    print("动物会跑")
    class dog(Animal):
    def play(self):
    print("dog can run")


    cat = Animal()
    print(type(cat))
    print(isinstance(cat,Animal))
    print(issubclass(dog,Animal))

    <class '__main__.Animal'>
    True
    True

    type的应用小场景

    def Sum(a,b):
    """

    :param a:
    :param b:
    :return:
    """
    if (type(a) == int or type(a) == float) and (type(b) == int or type(b) == float):
    return a + b
    else:
    print("输入类型错误")
    ret = Sum(9.99,9)
    print(ret) ps:在python里面三个双引号然后回车是文本注释,可以对你的代码进行阐述。

    四.方法和函数

     首先理解创建对象的概念,通过类来创建对象的时候,会生成一个兑现的命名空间然后把类的init方法下的属性都拿过来,再把类下面的方法名写到对象的命名空间里面,此时对于对象下的方法名就是一个绑定方法,当执行对象.方法的时候,实际上还是执行类下面的方法,在这里就能体现出绑定方法了。但对于类来说如果通过类名.方法调用。本质上还是一个函数。因此可以得出一个结论  对象.方法 = 方法   类.方法 = 函数  (实例方法)类方法classmethod 类.方法 = 方法 对象.方法 = 方法 (类方法和类属性一般都是比较推荐通过类调用) 最后一种是静态方法: staticclass 不管通过什么方式来调用始终都是函数。

    class Person:
    def __init__(self,name,age):
    self.name = name
    self.age = age
    @classmethod
    def eat(cls):
    print("this is a class method")

    @staticmethod
    def drink():
    print("this is a staic method")

    def sleep(self):
    print("this is a instance method")

    p = Person("jack",19)
    print(p.eat)
    print(Person.eat)
    print(Person.sleep)
    print(p.drink)
    print(p.sleep)

    <bound method Person.eat of <class '__main__.Person'>>
    <bound method Person.eat of <class '__main__.Person'>>
    <function Person.sleep at 0x0000013C3CD5E510>
    <function Person.drink at 0x0000013C3CD5E488>
    <bound method Person.sleep of <__main__.Person object at 0x0000013C3CD6A128>>

    判断是方法还是函数

    from types import FunctionType,MethodType
    print(isinstance(p.sleep,FunctionType))
    print(isinstance(p.sleep,MethodType))
    print(isinstance(p.eat,FunctionType))
    print(isinstance(p.eat,MethodType))
    print(isinstance(p.drink,FunctionType))
    print(isinstance(p.drink,MethodType))

    五.反射

      反射只用四个方法,常用的就hasattr和getattr

    hasattr(obj,str)判断对象里面是否有xx属性

    getattr(obj,str) 获取obj里面的str属性

    delattr(obj,str)删除obj里面的str属性

    setattr(obj, str,xx) 给obj设置str属性

    import daniu
    while 1:
    skill = input("请输入你要测试的功能: ")
    if hasattr(daniu,skill):
    new_skill = getattr(daniu,skill)
    if callable(new_skill):
    new_skill()
    else:
    print(f"{new_skill}不能被调用")
    else:
    print("还没有这个功能")
    代码解读:导入daniu模块,判断daniu里面是否有skill属性,如果有获取然后在判断是否可调用,如果可调用就执行否则直接打印不可调用。

    删除属性的例子:
    class Person:
    def __init__(self,name,age):
    self.name = name
    self.age = age
    def haha(self):
    print("haha")
    p = Person("ivy","18")
    print(hasattr(p,"haha"))
    fn = getattr(p,"haha")
    fn()
    delattr(p,"name")

    设置属性的例子
    setattr(Person,"eat", lambda self:print("我要吃"))  ps:person类 设置eat方法 通过匿名函数打印我要吃。

    六.约束

    约束有一种方式

    1.通过父类抛异常 raise ImplementedError  代表子类必须重写这个方法

    2.通过抽象类约束 没有具体的实例。导入abc模块的ABCmate 和abstractclass

    from abc import ABCclass,abstractclass

    class Foo(maetaclass=ABCclass):

        @abstractclass

        def login:pass

    实例1:抛异常

    class Foo:
    def login(self):
    #报错,抛出异常
    raise NotImplementedError("没有重写login")

    class Member(Foo):
    def login(self):
    print("普通人员登录")

    class Member_admin(Foo):
    def login(self):
    print("吧务登录")

    class Admin(Foo):
    def login(self):
    print("管理员登录")

    def login(obj):
    obj.login()

    m = Member()
    m_a = Member_admin()
    a = Admin()

    实例2抽象类
    from abc import ABCMeta,abstractmethod
    class Foo(metaclass=ABCMeta):
    @abstractmethod
    def login(self):pass

    class Member(Foo):
    def login(self):
    print("普通人员登录")

    class Member_admin(Foo):
    def login(self):
    print("吧务登录")

    class Admin(Foo):
    def login(self):
    print("管理员登录")

    def login(obj):
    obj.login()

    m = Member()
    m_a = Member_admin()
    a = Admin()

    login(m)
    login(m_a)
    login(a)

    七.继承

    
    
    class A:
    pass
    class B(A):
    pass

    py2:
    经典类 -> 默认不继承object
    新式类 -> 默认继承object
    py3:
    新式类

    万事万物皆为对象 -> 所有的东西都要继承object

      __mro__() 查看继承的顺序

    super(Branch, self).__init__(name,address) 
    super的两种用法:
    1.指定要从哪儿继承方法过来
    class A:
    def test(self):
    print("testA")
    class B(A):
    def test(self):
    print("testB")
    class C(B):
    def test(self):
    #print("testC")
    super(B, self).test() super的第一个参数可根据想访问那个方法来指定,如果想访问A里面的test 把一个参数写成B即可

    c = C()
    c.test()

    2.访问父类里面的构造方法
    class School:
    def __init__(self,name,adress):
    self.name = name
    self.address = adress
    class Branch(School):
    def __init__(self,name,address,leader):
    self.leader = leader
    super(Branch, self).__init__(name,address)

    b = Branch("beida","shahe","Jackson")
    print(b.name)

    补充点:通过类创建对象 类是通过type来创建的,type是什么鬼我也不知道......

    八.特殊特殊成员方法

    __doc__  打印类的描述信息

    class Person:
    """计算a,b 的和"""
    def __init__(self,name):
    self.name = name
    def eat(self,a,b):
    return a+b
    print(Person.__doc__)

    __module__表示当前操作的对象在哪个模块

    class M:
    def __init__(self,name):
    self.name = name
    print(M.__module__) ps:结果是main

    __class__表示当前操作的对象的类是什么

    __del__析构方法,当对象在内存中被释放的时候自动执行

    __call__对象后面加括号触发执行

    __dict__查看类或对象中的所有成员

    __str__如果一个类中定义了str方法,打印对象时默认输出该方法的返回值

    __getitem__,__setitem__,__delitem__ 用于索引操作

    class Foo(object):
     
        def __getitem__(self, key):
            print('__getitem__',key)
     
        def __setitem__(self, key, value):
            print('__setitem__',key,value)
     
        def __delitem__(self, key):
            print('__delitem__',key)
    
    obj = Foo()
     
    result = obj['k1']      # 自动触发执行 __getitem__
    obj['k2'] = 'alex'   # 自动触发执行 __setitem__
    del obj['k1']  

    __new__用于创建实例的 在init方法前执行

    __metaclass__ 定义一个类如何被创建

    例子详解:
    class Person:
    #c创建对象的时候自动调用init
    def __init__(self):
    print("我是特殊成员")
    #在对象加括号的时候自动调用
    def __call__(self):
    print("我是call")
    #with的时候自动调用
    def __enter__(self):
    print("我是enter")
    #离开with的时候自动调用
    def __exit__(self, exc_type, exc_val, exc_tb):
    print("我是exit")
    #执行[]会调用
    def __getitem__(self, item):
    print("我是getitem")
    return "haha"
    #执行p[key] = value的时候自动执行
    def __setitem__(self, key, value):
    print(key)
    print(value)
    def __delitem__(self, key):
    pass
    def __hash__(self): ps:hash必须返回一个数字
    print("我是hash")
    return 1
       #z执行==的时候自动执行
    def __eq__(self, other):
    print("这是eq")
    return True
    #执行加的时候自动执行
    def __add__(self, other):
    print("这是加")
    p = Person()

    __new__详细说明__new__在init之前执行
    创建对象的时间轴,首先写好一个类 然后加载类,
    new开辟一个内存空间,(构造) 然后在执行init
    创建类的时候如果不写new自动执行object里面的new开辟一个新的内存空间

    1. 加载类 2. 开辟内存(__new__) 3. 初始化(__init__) 4. 使⽤用对象xxxxxxxxx

    例子1:
    class A:
    def __init__(self):
    print("我是init")
    def __new__(cls, *args, **kwargs):
    print("我是new")
    return object.__new__(cls) #开辟内存
    a = A() #不写new默认使用object中的new

    例子2:new的单例模式
    #单例模式(恶汉式),在内存里面保存一个对象,并且能反复使用
    class Singleton:
    __instance = None
    def __init__(self):
    print("我是singleton")
    def __new__(cls, *args, **kwargs):
    if Singleton.__instance:
    return Singleton.__instance
    else:
    obj = object.__new__(cls)
    Singleton.__instance = obj
    return Singleton.__instance
    s1 = Singleton()
    s2 = Singleton()
    print(id(s1),id(s2))
    #目前问题:高并发的情况下,这个单例有问题

    九.异常处理

    try:
    xxxx
    except 错误:
    xxx
    finally:
    最终的...

    traceback
    查看调用过程的报错信息

    raise 抛出异常对象
    定义类的时候继承Exception就是异常类

    try:
    print("各种操作....")
    except ZeroDivisionError as e:
    print("除数不不能是0")
    except FileNotFoundError as e:
    print("⽂文件不不存在")
    except Exception as e:
    print("其他错误")
    else:
    '''保护不不抛出异常的代码, 当try中⽆无异常的时候执⾏行行'''
    finally: '''最后总是要执⾏行行我'''

    import traceback  # 可以看见堆栈信息(谁掉了谁)
    try:
    print(1/0)
    except Exception:
    print("报错了")
    print(traceback.format_exc()) #查看调用过程的报错信息

    自定义异常
    class shujuleixingcuowu(Exception): #只要继承了Exception就是异常类
    pass

    def func(a,b):
    """
    计算a+b的结果
    :param: a必须是数字
    :param: b必须是数字
    :return: 和
    """
    if (type(a) == int or type(a) == float) and (type(b) == int or type(b) == float):
    return a + b
    else:
    raise shujuleixingcuowu("a和b的数据类型错误")

    补充知识点

    修改@property属性里面的值

    class Person:
    def __init__(self,name):
    self.__name = name
    @property
    def name(self):
    return self.__name+"_sb"
    @name.setter
    def name(self,_name):
    self.__name = _name

    p = Person("Jack")
    print(p.name)
    p.name = "haha"
    print(p.name)

    十.hashlib模块

    import hashlib  #机密包 最著名的是MD5用来验证文件或者密码的一致性
    password = "123456"
    obj = hashlib.md5()
    obj.update(password.encode("utf-8")) #必须是字节
    s = obj.hexdigest()
    print(s)

    加盐
    import hashlib 
    password = "123456"
    obj = hashlib.md5(b'wang') 在这儿加
    obj.update(password.encode("utf-8")) #必须是字节
    s = obj.hexdigest()
    print(s)

    例子:实现登录和注册功能
    import hashlib
    username = ""
    password = ""
    def my_md5(s):
    obj = hashlib.md5(b'asdasd')
    obj.update(s.encode("utf-8"))
    return obj.hexdigest()

    def reg():
    uname = input("请输入用户名:")
    upwd = input("请输入密码:")
    global username
    username = uname
    global password
    password = my_md5(upwd)
    print(password)

    def login():
    uname = input("请输入用户名:")
    upwd = input("请输入密码:")
    if uname == username and my_md5(upwd) == password:
    print("登录成功")
    else:
    print("登录失败")
    reg()
    login()

    十一.logging日志模块

    单文件记录日志

    #logging  记录日志
    import logging
    # filename: ⽂文件名
    # format: 数据的格式化输出. 最终在⽇日志⽂文件中的样⼦子
    # 时间-名称-级别-模块: 错误信息
    # datefmt: 时间的格式
    # level: 错误的级别权重, 当错误的级别权重⼤大于等于leval的时候才会写⼊入⽂文件
    logging.basicConfig(filename='x1.txt',
    format='%(asctime)s - %(name)s - %(levelname)s - %(module)s: %(message)s',
    datefmt='%Y-%m-%d %H:%M:%S',
    level=0) # 当前配置表示 10以上的分数会被写⼊入⽂文件
    logging.critical("报错了") #最高级别#50
    logging.error("报错了") #40
    logging.warn("1")
    logging.warning("警告") #警告30
    logging.info("信息")
    logging.debug("调错") #10
    logging.log(999,"地球飞了")

    结合自定义异常类打印日志
    #logging  记录日志
    import logging
    # # filename: ⽂文件名
    # # format: 数据的格式化输出. 最终在⽇日志⽂文件中的样⼦子
    # # 时间-名称-级别-模块: 错误信息
    # # datefmt: 时间的格式
    # # level: 错误的级别权重, 当错误的级别权重⼤大于等于leval的时候才会写⼊入⽂文件
    logging.basicConfig(filename='x1.txt',
    format='%(asctime)s - %(name)s - %(levelname)s - %(module)s: %(message)s',
    datefmt='%Y-%m-%d %H:%M:%S',
    level=0) # 当前配置表示 10以上的分数会被写⼊入⽂文件
    logging.critical("报错了") #最高级别#50
    logging.error("报错了") #40
    logging.warn("1")
    logging.warning("警告") #警告30
    logging.info("信息")
    logging.debug("调错") #10
    logging.log(999,"地球飞了")

    import logging
    import traceback
    class JackError(Exception):
    pass
    for i in range(10):
    try:
    if i % 3 ==0:
    raise FileNotFoundError("文件不存在")
    elif i % 3 == 1:
    raise KeyError
    elif i % 3 == 2:
    raise JackError("Jackexception")
    except FileNotFoundError:
    val = traceback.format_exc()
    logging.error(val)
    except KeyError:
    val = traceback.format_exc()
    logging.error(val)
    except JackError:
    val = traceback.format_exc()
    logging.error(val)
    except Exception:
    val = traceback.format_exc()
    logging.error(val)

    多日志文件系统
    import logging

    # 创建⼀一个操作⽇日志的对象logger(依赖FileHandler)
    file_handler = logging.FileHandler('l1.log', 'a', encoding='utf-8')
    file_handler.setFormatter(logging.Formatter(fmt="%(asctime)s - %(name)s - %(levelname)s -%(module)s: %(message)s"))
    logger1 = logging.Logger('用户名1', level=logging.ERROR)
    logger1.addHandler(file_handler)
    logger1.error("错了错了")

    # 再创建⼀一个操作⽇日志的对象logger(依赖FileHandler
    file_handler2 = logging.FileHandler('l2.log', 'a', encoding='utf-8')
    file_handler2.setFormatter(logging.Formatter(fmt="%(asctime)s - %(name)s %(levelname)s -%(module)s: %(message)s"))
    logger2 = logging.Logger('用户名2', level=logging.ERROR)
    logger2.addHandler(file_handler2)
    logger2.error("好像真的错了")
    We are down, but not beaten. tested but not defeated.
  • 相关阅读:
    HTTP状态码
    HTTP详解教程 / HTTP 响应头信息 HTTP 响应头信息
    HTTP请求方法
    HTTP 消息结构
    HTTP 简介
    Session 工作原理
    CSS 布局
    css float 浮动
    CSS 布局
    css position定位
  • 原文地址:https://www.cnblogs.com/guniang/p/10898352.html
Copyright © 2011-2022 走看看