zoukankan      html  css  js  c++  java
  • day018反射及区分函数和方法,md5加密

    本节主要内容:

    1. isinstance, type, issubclass 三个面向对象的内置函数
    2. 区分函数和方法
    3. 反射(重点)
    4. md5加密(数字签名、电子签章的原理)

    一、三个关于面向对象的内置函数

    1、issubclass()

    作用:判断xxx是否是yyy类型的子类
    object是所有类的根,是面向对象的祖宗

    fe:

    class Foo(object):
        pass
    
    class Bar(Foo):
        pass
    
    class FooBar(Bar):
        pass
    
    print(issubclass(Bar, Foo)) # True
    print(issubclass(Foo, Bar)) # False
    print(issubclass(FooBar, Foo)) # True 可以隔代判断
    
    
    print(issubclass(Foo, object))
    print(issubclass(Bar, object))
    print(issubclass(FooBar, object))
    
    object是所有类的根. 面向对象的祖宗

    2、type

    作用: 精准的返回该对象的类型

    fe1:判断数据类型

    print(type("你好")) # <class 'str'> 返回该对象的数据类型
    
    class Animal:
        pass
    
    class Cat(Animal):
        pass
    
    c = Cat()
    
    print(type(c)) # 可以精准的返回数据类型

    fe2: 计算a+b的结果 数学运算

    def cul(a, b):
        if (type(a) == int or type(a) == float) and (type(b) == int or type(b) == float):
            return a + b
        else:
            print("不行. 不能帮你计算")
    
    print(cul(10, "胡辣汤"))

    3、isinstance()

    作用:判断xxx是否是yyy类型的数据,包括父类
    只能向上

    fe1:

    class Animal:
        pass
    
    class cat(Animal):
        pass
    
    class BoSiCat(cat):
        pass
    
    c = cat()
    
    print(isinstance(c, Animal))  # 判断这个对象是否是 xxx的一种,包括父类
    
    print(isinstance(c, BoSiCat))  # 报错,只能向上判断,不能向下
    
    print(type(c, Animal))  # 只能精准判断属于cat, 不能找到父类

    fe2: 判断是否是迭代器类型的数据

    from collections import Iterator # 引入
    lst = []
    it = lst.__iter__() # list_iterator
    print(isinstance(it, Iterator)) # True

    二、区分函数和方法(面向对象中)

    1、野路子判断

    通过打印

    fe1:

    查看类中的方法和函数
    class Car:
        def run(self): # 实例方法
            print("我是车, 我会跑")
    
        @staticmethod
        def cul():
            print("我会计算")
    
        @classmethod
        def jump(cls):
            print("我会jump")
    
    # 实例方法 <bound method Car.run of <__main__.Car object at 0x000001E9166B73C8>>
    c = Car()
    1
    "str"
    print(c.run) # <bound method Car.run of <__main__.Car object at 0x000001E9166B73C8>>
    Car.run(c) #  通过类名也可以访问实例方法. 不要这么干
    print(Car.run) # <function Car.run at 0x000002454C748AE8>
    # 实例方法:
    #     1. 用对象.方法   方法
    #     2. 类名.方法     函数
    #
    # 静态方法
    #    都是函数
    print(c.cul) # <function Car.cul at 0x0000024BA2658BF8>
    print(Car.cul) # <function Car.cul at 0x0000024BA2658BF8>
    
    # 类方法都是方法
    print(c.jump) # <bound method Car.jump of <class '__main__.Car'>>
    print(Car.jump) # <bound method Car.jump of <class '__main__.Car'>>
    # 对象.方法
    # 万事万物皆为对象
    # 我们写的类. 也是对象.  可以创建对象

    2、官方的办法

    用程序来分辨
    from types import FunctionType, MethodType
    print(isinstance(xx, FunctionType)))
    print(isinstance(xx, MethodType)))
    所有的方法都是MethodType
    所有的函数都是FunctionType

    fe:

    from types import FunctionType, MethodType
    
    class Car:
        def run(self): # 实例方法
            print("我是车, 我会跑")
    
        @staticmethod
        def cul():
            print("我会计算")
    
        @classmethod
        def jump(cls):
            print("我会jump")
    
    # 实例方法:
    #     1. 用对象.方法   方法
    #     2. 类名.方法     函数
    c = Car()
    # print(isinstance(c.run, FunctionType)) # False
    # print(isinstance(Car.run, FunctionType)) # True
    # print(isinstance(c.run, MethodType)) # True
    # print(isinstance(Car.run, MethodType)) # False
    
    # 静态方法 都是函数
    # print(isinstance(c.cul, FunctionType)) # True
    # print(isinstance(Car.cul, FunctionType)) # True
    # print(isinstance(c.cul, MethodType)) # False
    # print(isinstance(Car.cul, MethodType)) # False
    
    # 类方法都是方法
    print(isinstance(c.jump, FunctionType)) # False
    print(isinstance(Car.jump, FunctionType)) # False
    print(isinstance(c.jump, MethodType)) # True
    print(isinstance(Car.jump, MethodType)) # True
    
    # FunctionType:所有的函数
    # MethodType: 所有的方法

    3、区分函数和方法的结论

    1. 实例方法:

    用类名访问. 函数
    用对象访问. 方法

    2. 静态方法

    都是函数

    3. 类方法

    都是方法

    三、反射

    常用(掌握):
    hasattr(对象, 属性(字符串))  判断是否有这个属性,返回True或者False, # 判断 xxx中是否有 xxx
    getattr(对象, 属性(字符串))  从对象中获取到xxx属性
    不太常用:
    setattr(对象, 属性, 值)     设置,原来有就修改,没有就修改
    delattr(对象, 属性)         从对象中删除xxx属性

    fe1:

    反射
    import master  # 引入模块,在自己这边开辟内存,存放master模块(一个写好的py文件)
    
    def chi():
        print("大牛说的不对,我要换")
    
    setattr(master, "chi", chi) # 给xxx模块的chi替换成我的chi,跟字典一样,在自己这边的内存,修改函数
    setattr(master, "haha", chi) # 没有就新增,新增haha函数
    
    delattr(master, "name") # 删除"name"这个变量
    print(master.name)
    
    setattr(master, "wife", "皮蛋")  # 有就是修改,没有就新增
    print(master.wife)  # 模块名.变量名 或 函数名 或其他,就是调用
    
    
    while 1:
        s = input("请输入你要测试的功能:")  # 输入函数名
    
        if hasattr(master, s):  # 判断 xxx中是否有 xxx
            fn = getattr(master, s)  # 在 xxx中获取到 xxx
            fn()
        else:
            print("没有这个功能喔")
    
    
    普通的获取方法
    
    lst = ["chi", "he", "shui"]
    
    for k, item in enumerate(lst):  # 枚举,enumerate(枚举的对象)
        print(k, item)

    fe2: 属性存储在对象里,方法存储在类里

    class Car:
        def __init__(self, cloro, pai, price):
            self.cloro =cloro
            self.pai = pai
            self.price = price
    
        def fly(self):
            print("车在飞")
    
    c = Car("大红色", "宝马", 1000000)
    
    setattr(Car, "fly", lambda self: print("我让他飞的,不是他自己飞") ) # 方法存在类里,所以用类来操作
    c.fly()
    
    setattr(c, "cloro", "黑色")  # 属性存在对象里,所以用对象来进行操作修改
    print(c.cloro)
    
    # print(getattr(c, "cloro"))  # 属性存在对象里,所以要用对象去拿
    # print(getattr(Car, "cloro"))  # 报错   类中不存属性
    # print(c.cloro)
    
    # delattr(Car, "fly")
    # delattr(c,"cloro")  # 可以操作我们的类或者对象

    四、md5加密

    md5特点: 不可逆的一种加密方式
    最多用在密码加密上

    1、步骤

    import hashlib  # 引入
    obj = hashlib.md5(加盐)  # 加盐=二次加密,md5出来太久,可以被查询,二次加密后就无法查询到了
    obj.update(铭文的bytes)
    obj.hexdigest() 获取密文

    2、md5的使用

    import hashlib
    def jiami(content):
        obj = hashlib.md5(SALT)  # 创建md5对象,并进行加密
        obj.update(content.encode("utf-8"))  # 给obj设置铭文
        return obj.hexdigest()  # 获取到密文

    fe1: 使用实例,注册和登录的实例

    import hashlib
    
    SALT = b"abcdefghijklmnjklsfdafjklsdjfklsjdak"
    
    # 创建md5的对象
    obj = hashlib.md5(SALT) # 加盐
    # 给obj设置铭文
    obj.update("alex".encode("utf-8"))
    # 获取到密文
    miwen = obj.hexdigest()
                 # f4c17d1de5723a61286172fd4df5cb83
                 # 534b44a19bf18d20b71ecc4eb77c572f
    print(miwen) # 534b44a19bf18d20b71ecc4eb77c572f

    fe2: 注册和登录的实例

    import hashlib
    
    SALT = b"abcdefghijklmnjklsfdafjklsdjfklsjdak" # 一定要byte类型的加盐
    
    # 注册
    # username = input("请输入你的用户名:")   # alex
    # password = input("请输入你的密码:")
    # password = jiami(password) # c3d4fe3dce88533a8b50cf2e9387c66d
    # print(password)
    
    # 登录
    uname = "alex"
    upwd = "c3d4fe3dce88533a8b50cf2e9387c66d"
    
    username = input("请输入你的用户名:")
    password = input("请输入你的密码:")
    
    if uname == username and upwd == jiami(password):
        print("登录成功")
    else:
        print("失败")
  • 相关阅读:
    「SDOI2018」物理实验
    「SDOI 2018」战略游戏
    「CodeChef Dec13 REALSET」 Petya and Sequence 循环卷积
    关于微信卡券投放code接口报错原因
    composer update maatwebsite/excel 之后 在linux机子上出现500解决方案
    开启mysql 服务【window】
    thinkphp在linux上部署环境(500情况)
    如何推广微信小程序到企业微信
    linux 阿里云远程连接mysql
    php7以上 不支持mcrypt_module_open方法问题【微信开放平台】
  • 原文地址:https://www.cnblogs.com/yipianshuying/p/9936671.html
Copyright © 2011-2022 走看看