python D18 反射与md5 加密

# 本节主要内容:
# 1、isinstance, type, issubclass
# 2、区分函数和方法
# 3、反射(重点)

# 一、isinstance, type, issubclass
# isinstance(): 这个内置函数可以帮我们判断xxx类是否是yyy类型的⼦类.
# 语法issubclass(x,y):判断x是不是y的子类型 可以隔代,是为True 不是为False

# class Base:
# pass
# class Foo(Base):
# pass
# class Bar(Foo):
# pass
# print(issubclass(Bar, Foo)) # True
# print(issubclass(Foo, Bar)) # False
# print(issubclass(Bar, Base)) # True

# type 在前⾯的学习期间已经使⽤过了. type(obj) 表⽰查看obj是由哪个类创建的.
# type可以帮我们判断xxx是否是xxx数据类型的、你在进⾏计算的时候. 先判断好要计算的数据类型必须是int或者float. 这样的计算才有意义.

# class Foo:
# pass
# obj = Foo()
# print(obj, type(obj)) # 查看obj的类

# isinstance也可以判断xxx是yyy类型的数据. 但是isinstance没有type那么精准.
# isinstance可以判断该对象是否是xxx家族体系中的(只能往上判断)

# class Base:
# pass
# class Foo(Base):
# pass
# class Bar(Foo):
# pass
# print(isinstance(Foo(), Foo)) # True
# print(isinstance(Foo(), Base)) # True
# print(isinstance(Foo(), Bar)) # False

# ⼆. 区分函数和⽅法
# 我们之前讲过函数和⽅法. 这两样东⻄如何进⾏区分呢? 其实很简单. 我们只需要打印⼀
# 下就能看到区别的.
# def func():
# pass
# print(func) # <function func at 0x10646ee18>
# class Foo:
# def chi(self):
# print("我是吃")
# f = Foo()
# print(f.chi()) # 我是吃 None ### 加括号才是调用函数
# print(f.chi) # <bound method Foo.chi of <__main__.Foo object at0x10f688550>>

# 函数在打印的时候. 很明显显⽰的是function. ⽽⽅法在打印的时候很明显是method.
# 那在这⾥. 我要告诉⼤家. 其实并不⼀定是这样的. 看下⾯的代码:
# class Foo:
# def chi(self):
# print("我是吃")
# @staticmethod
# def static_method():
# pass
# @classmethod
# def class_method(cls):
# pass
# f = Foo()
# print(f.chi) # <bound method Foo.chi of <__main__.Foo object at0x10f688550>>
#
# print(Foo.chi) # <function Foo.chi at 0x10e24a488>
#
# print(Foo.static_method) # <function Foo.static_method at 0x10b5fe620>
#
# print(Foo.class_method) # bound method Foo.class_method of <class'__main__.Foo'>>
#
# print(f.static_method) # <function Foo.static_method at 0x10e1c0620>
#
# print(f.class_method) #<bound method Foo.class_method of <class'__main__.Foo'>>

# 总结:
# 实例方法:如果用实例对象去访问,就是方法,乳沟用类名去访问就是函数
# 静态方法:不论什么情况下都是函数
# 类方法:不论什么情况下都是方法

# 那如何⽤程序来帮我们分辨. 到底是⽅法还是函数呢? ⾸先, 我们要借助于types模块.
# 所有的⽅法都是MethodType的实例
# 所有的函数都是FunctionType的实例
# from types import MethodType, FunctionType
# def func():
# pass
# print(isinstance(func, FunctionType)) # Tru
# print(isinstance(func, MethodType)) # False
#
# class Foo:
# def chi(self):
# print("我是吃")
# @staticmethod
# def static_method():
# pass
# @classmethod
# def class_method(cls):
# pass
# obj = Foo()
# print(type(obj.chi)) # method
# print(type(Foo.chi)) # function
# print(isinstance(obj.chi, MethodType)) # True
# print(isinstance(Foo.chi, FunctionType)) # True
# print(isinstance(Foo.static_method, FunctionType)) # True
# print(isinstance(Foo.static_method, MethodType)) # False
# print(isinstance(Foo.class_method, FunctionType)) # False
# print(isinstance(Foo.class_method, MethodType)) # True

# from types import MethodType, FunctionType
# class Foo:
# @classmethod
# def func1(self):
# pass
# @staticmethod
# def func2(self):
# pass
# def func3(self):
# pass
# def func4(self):
# pass
# lst = [func1, func2, func3]
# obj = Foo()
# Foo.lst.append(obj.func4)
# for item in Foo.lst:
# print(isinstance(item, MethodType)) # 这是啥,怎肥四

# 练习. 写⼀个函数. 判断传递进来的内容是函数还是⽅法?
# def func(content):
# from types import MethodType, FunctionType
# x = isinstance(content, MethodType)
# if x == True:
# print("是方法")
# else:
# print("是函数")

# 三. 反射.
# ⾸先, 我们看这样⼀个需求, 说, 有个⼤⽜, 写了⼀堆特别⽜B的代码. 然后放在了⼀个py
# ⽂件⾥(模块), 这时, 你想⽤这个⼤⽜写的东⻄. 但是呢. 你⾸先得知道⼤⽜写的这些代码都是
# ⼲什么⽤的. 那就需要你把⼤⽜写的每⼀个函数跑⼀下. 摘⼀摘⾃⼰想⽤的内容. 来咱们模拟
# 这样的需求, ⾸先, ⼤⽜给出⼀个模块.
# master.py
def chi():
print("⼤⽜⼀顿吃100个螃蟹")
def he():
print("⼤⽜⼀顿喝100瓶可乐")
def la():
print("⼤⽜不⽤拉")
def shui():
print("⼤⽜⼀次睡⼀年")

# 接下来, 到你了. 你要去⼀个⼀个的调⽤. 但是呢. 在调⽤之前. ⼤⽜告诉你了. 他写了哪
# 些哪些⽅法. 那现在就可以这么来办了
# import master
# while 1:
# print("""作为⼤⽜, 我帮你写了:
# chi
# he
# la
# shui
# 等功能. ⾃⼰看看吧""")
# gn = input("请输⼊你要测试的功能:")
# if gn == 'chi':
# master.chi()
# elif gn == "he":
# master.he()
# elif gn == "la":
# master.la()
# elif gn == "shui":
# master.shui()
# else:
# print("⼤⽜就这⼏个功能. 别搞事情")
# 写是写完了. 但是.....如果⼤⽜现在写了100个功能呢? 你的判断要判断100次么? 太累
# 了吧. 现有的知识解决不了这个问题. 那怎么办呢? 注意看. 我们可以使⽤反射来完成这样的
# 功能. 非常的简单. 想想. 这⾥我们是不是让⽤户输入要执⾏的功能了. 那这个功能就是对应
# 模块⾥的功能. 那也就是说. 如果能通过字符串来动态访问模块中的功能就能解决这个问题.
# 好了. 我要告诉你. 反射解决的就是这个问题. 为什么叫反射? 反着来啊. 正常是我们先引入
# 模块, 然后⽤模块去访问模块⾥的内容. 现在反了. 我们⼿动输入要运⾏的功能. 反着去模块
# ⾥找. 这个就叫反射
# import master
# # while 1:
# # print("""作为⼤⽜, 我帮你写了:
# # chi
# # he
# # la
# # shui
# # 等功能. ⾃⼰看看吧""")
# # gn = input("请输⼊你要测试的功能:")
# # # niuB版
# # func = getattr(master, gn)
# # func()

# 反射有四个函数、都能做用在不同文件中只要应用 import 文件名(同意层级的文件)
# hasattr(对象, 属性(字符串)) 对象中是否有xxx属性
# getattr(对象, 属性(字符串)) 从对象中获取到xxx属性
#
# setattr(对象, 属性x, 值) 查找替换,如果对象中原来有属性x,则对应的覆盖x的值
# setattr:当用于全局是可以产生行的属性,如果作用在局部或者在类中则不能
# setattr(对象, 属性x, 值) 属性x = 值
# delattr(对象, 属性) 从对象中删除xxx属性

# class Car:
# def __init__(self, name, pai, color, price):
# self.name = name
# self.pai = pai
# self.color = color
# self.price = price
# def da(self):
# print("我的车会打人")
#
# c = Car("布加迪", "深B6666", "黑色", "88888888")
#
# print(hasattr(c, "name")) # Ture
# print(hasattr(Car, "name")) # False 车的名字不是类名的名字 分清楚是谁的属性
# #
# print(getattr(c, "name")) # 从c中获取"name"这个属性 # 布加迪
# setattr(c, "color", "骚红") # 将c中颜色替换成骚红
# print(c.color) # 骚红

# setattr(Car, "da", lambda x: print("我的车很能打"))
# c.da() # 我的车很能打 用lambda函数去替换da()


# delattr(c, "name")
# print(c.name) #AttributeError: 'Car' object has no attribute 'name'

# delattr(Car, "da")
# c.da() #'Car' object has no attribute 'da'

# MD5加密
# md5特点: 不可逆的一种加密方式
# 最多用在密码加密上,保护用户登录密码隐私、防止泄露防止反推
# 步骤:
# 1、引入模块:import hashlib
# 2、创建md5对象 obj = hashlib.md5(SALT) SALT = b"abcdefghijklmnjklsfdafjklsdjfklsjdak" SALT在这里是给md5对象加料使密文不能反推密码
# 3、给obj设置铭文(铭文是以bytes类型) obj.update("alex".encode("utf-8"))
# 4、获取密文 miwen = obj.hexdigest() print(miwen)

# import hashlib # 引入模板
# obj = hashlib.md5()
# obj.update("alex123".encode("utf-8")) # alex123密码 给密码加密
# miwen = obj.hexdigest()
# print(miwen) #b75bd008d5fecb1f50cf026532e8ae67 容易破解

# import hashlib # 引入模板 在文件开始应用一次就行
# SALT = b"abcdefghijklmnjklsfdafjklsdjfklsjdak" 加料
# obj = hashlib.md5(SALT) # 创建md5对象 SALT加料
# obj.update("alex123".encode("utf-8")) # 给obj设置铭文 # alex123密码 给密码加密
# miwen = obj.hexdigest() # 获取密文
# print(miwen) #02e42026170e2a48fda8121b7c9dcb52 加料版 无法破解

# md5的使用 用户注册登录 密码隐私保护
# 先定义一份md5加密函数
# import hashlib
# AAAA = b"ffsgsshshshjjejehryrsgsfgsfs"
# def jiami(content):
# obj = hashlib.md5(AAAA)
# obj.update(content.encode("utf-8"))
# return obj.hexdigest()
#
# # 用户注册
# username = input("请输入你注册的账号:")
# password = input("请输入你注册的密码:")
# password = jiami(password)
# print(password) # 密码2131 拿到的密文5545ec2bdf0dcb39023651a3306f995f
#
# # 用户登录
# dusername = input("请输入你的账号:")
# dpassword = input("请输入你的密码:")
# dpassword = jiami(dpassword) # 对输入的密码加密
# if dusername == username and dpassword == password: # 判断登录的密码密文和注册密码的密文是否相同
# print("登录成功")
# else:
# print("登录失败")
原文地址:https://www.cnblogs.com/z520h123/p/9937302.html