构造方法
# __init__ 初始化方法
# __new__  构造方法 : 创建一个对象
class A:
    def __init__(self):
        self.x = 1
        print("in init function")

    # __new__构造方法相当于java中的构造方法,创建对象时调用
    def __new__(cls, *args, **kwargs):
        print("in new function")
        return object.__new__(cls, *args, **kwargs)


a1 = A()
a2 = A()
a3 = A()
print(a1)
print(a2)
print(a3)
单例模式
# 单例模式
# 一个类 始终 只有 一个 实例
# 当你第一次实例化这个类的时候 就创建一个实例化的对象
# 当你之后再来实例化的时候 就用之前创建的对象

class A:
    # 静态成员变量
    __instance = False

    def __init__(self, name, age):
        self.name = name
        self.age = age

    # 一个类始终只有一个实例
    def __new__(cls, *args, **kwargs):
        if cls.__instance:
            return cls.__instance
        cls.__instance = object.__new__(cls)
        # 返回object.__new__(cls)静态对象(__instance)
        return cls.__instance


xiaohu = A("xiaohu", 18)
xiaohu.cloth = "小棉袄"
dawei = A("大卫", 28)
print(dawei)
print(xiaohu)
print(dawei.name)  # 大卫
print(xiaohu.name)  # 大卫
print(dawei.cloth)  # 小棉袄
__eq__和__hash__
class A:
    def __init__(self, name):
        self.name = name

    # 相当于java的equals(Object obj)方法
    def __eq__(self, other):
        print("equals方法被调用了!")
        if self.__dict__ == other.__dict__:
            return True
        else:
            return False


ob1 = A('egon')
ob2 = A('egg')
print(id(ob1))  # 2448070652424
print(id(ob2))  # 2448072162664
# 两个对象比较的是内存地址,ob1 == ob2时调用__eq__()方法
print(ob1 == ob2)  # False
class A:
    def __init__(self, name, sex):
        self.name = name
        self.sex = sex

    # 相当于java中的hashCode()方法
    def __hash__(self):
        return hash(self.name + self.sex)


a = A('egon', '')
b = A('egon', 'nv')
print(hash(a))  # -9040726938826711162,执行__hash__()方法
print(hash(b))  # -1239659129338211027,执行__hash__()方法


# 内置函数 内置的模块 内置的基础类型 < --- >类的内置方法
# ==    __eq__
# len() __len__

# 100 名字 和 性别 年龄不同
# set
# class A:
#     def __init__(self,name,sex,age):
#         self.name = name
#         self.sex = sex
#         self.age = age
#
#     # def __eq__(self, other):
#     #     if self.name == other.name and self.sex == other.sex:
#     #         return True
#     #     return False
#
#     def __hash__(self):
#         return hash(self.name + self.sex)
# a = A('egg','',38)
# b = A('egg','',37)
# print(set((a,b)))   # unhashable

# set 依赖对象的 hash eq


"""
关于equals()方法,经常说的就是比较的是内容(与==比较的地址相对)
则有:

hashcode不相同,用equals()方法判断的返回的一定为false。

hashcode相同,equals()方法返回值不能确认,可能为true,可能为false。

object对象中的 public boolean equals(Object obj),对于任何非空引用值 x 和 y,当且仅当 x 和 y 引用同一个对象时,此方法才返回 true;
注意:当此方法被重写时,通常有必要重写 hashCode 方法,以维护 hashCode 方法的常规协定,该协定声明相等对象必须具有相等的哈希码。如下:
(1)当obj1.equals(obj2)为true时,obj1.hashCode() == obj2.hashCode()必须为true 
(2)当obj1.hashCode() == obj2.hashCode()为false时,obj1.equals(obj2)必须为false
如果不重写equals,那么比较的将是对象的引用是否指向同一块内存地址,重写之后目的是为了比较两个对象的value值是否相等。特别指出利用equals比较八大包装对象
(如int,float等)和String类(因为该类已重写了equals和hashcode方法)对象时,默认比较的是值,在比较其它自定义对象时都是比较的引用地址
hashcode是用于散列数据的快速存取,如利用HashSet/HashMap/Hashtable类来存储数据时,都是根据存储对象的hashcode值来进行判断是否相同的。
这样如果我们对一个对象重写了euqals,意思是只要对象的成员变量值都相等那么euqals就等于true,但不重写hashcode,那么我们再new一个新的对象,
当原对象.equals(新对象)等于true时,两者的hashcode却是不一样的,由此将产生了理解的不一致,如在存储散列集合时(如Set类),将会存储了两个值一样的对象,
导致混淆,因此,就也需要重写hashcode()


"""

 


hashlib
# 登录认证
# 加密 --> 解密
# 摘要算法
# 两个字符串 :
# import hashlib   # 提供摘要算法的模块
# md5 = hashlib.md5()
# md5.update(b'123456')
# print(md5.hexdigest())
#aee949757a2e698417463d47acac93df


# 不管算法多么不同,摘要的功能始终不变
# 对于相同的字符串使用同一个算法进行摘要,得到的值总是不变的
# 使用不同算法对相同的字符串进行摘要,得到的值应该不同
# 不管使用什么算法,hashlib的方式永远不变

# import hashlib   # 提供摘要算法的模块
# sha = hashlib.md5()
# sha.update(b'alex3714')
# print(sha.hexdigest())

# sha 算法 随着 算法复杂程度的增加 我摘要的时间成本空间成本都会增加

# 摘要算法
# 密码的密文存储
# 文件的一致性验证
    # 在下载的时候 检查我们下载的文件和远程服务器上的文件是否一致
    # 两台机器上的两个文件 你想检查这两个文件是否相等

# 用户注册
# 用户 输入用户名
# 用户输入 密码
# 明文的密码进行摘要 拿到一个密文的密码
# 写入文件

# 用户的登录
# import hashlib
# usr = input('username :')
# pwd = input('password : ')
# with open('userinfo') as f:
#     for line in f:
#         user,passwd,role = line.split('|')
#         md5 = hashlib.md5()
#         md5.update(bytes(pwd,encoding='utf-8'))
#         md5_pwd = md5.hexdigest()
#         if usr == user and md5_pwd == passwd:
#             print('登录成功')


# 1234567890
# abcdefghijk
# 6位
# md5
# 撞库

# 加盐
import hashlib   # 提供摘要算法的模块
# md5 = hashlib.md5(bytes('',encoding='utf-8'))
# # md5 = hashlib.md5()
# md5.update(b'123456')
# print(md5.hexdigest())

# 动态加盐
# 用户名 密码
# 使用用户名的一部分或者 直接使用整个用户名作为盐
# import hashlib   # 提供摘要算法的模块
# md5 = hashlib.md5(bytes('',encoding='utf-8')+b'')
# # md5 = hashlib.md5()
# md5.update(b'123456')
# print(md5.hexdigest())

#import hashilib
# 做摘要计算的 把字节类型的内容进行摘要处理
# md5 sha
# md5  正常的md5算法 加盐的 动态加盐


# 文件的一致性校验
# 文件的一致性校验这里不需要加盐
# import hashlib
# md5 = hashlib.md5()
# md5.update(b'alex')
# md5.update(b'3714')
# print(md5.hexdigest())

# 作业: 对一个文件进行摘要算法,最后计算出这个文件的md5值。

userinfo

alex|aee949757a2e698417463d47acac93df|Teacher