day28_python
参考Eva_J的博客,原文连接:https://www.cnblogs.com/Eva-J/p/7277026.html
要导的文件
import hashlib
from random import shuffle
from random import choice
from collections import namedtuple
对象:属性和调用方法
dic = {'k': 'v'}
dic['k'] = 'v'
class Foo:
def __init__(self, name, age, sex) -> None:
self.name = name
self.age = age
self.sex = sex
def __getitem__(self, item):
if hasattr(self, item):
return self.__dict__[item]
def __setitem__(self, key, value):
self.__dict__[key] = value
def __delitem__(self, key):
del self.__dict__[key]
f = Foo('egon', 38, '男')
print(f['name']) # a等效于item
f['hobby'] = '男'
print(f['hobby'], f.hobby)
# del f.hobby # object类原生支持的。 __delattr__方法
# print(f.__dict__)
del f['hobby'] # 删除不了,需要自己在类中实现__delitem__方法
print(f.__dict__) # 字典是这样实现的,列表也是通过[]的形式去访问值用item方法
# 参数陷阱,可变数据类型不要作为默认参数
重写方法
new
# __init__ 初始化方法
# __new__ 构造方法,创建一个对象
class A:
def __init__(self):
self.x = 1
print('in init function')
def __new__(cls, *args, **kwargs): # 这是self的来源,平时情况下不需要实现new
print('in new function')
return object.__new__(A, *args, **kwargs)
a = A()
print(a.x)
单例模式
一个类始终只有一个实例,当第一次实例化这个类的时候就创建一个实例化的对象,再来实例化的时候,使用之前创建的对象
class A:
__instance = False
def __init__(self, name, age):
self.name = name
self.age = age
print('in init function')
def __new__(cls, *args, **kwargs): # 自己有new方法就用自己的
if cls.__instance:
return cls.__instance
cls.__instance = object.__new__(A)
return cls.__instance
egon = A('egg', 38)
egon.cloth = '羽绒服'
nezh = A('nazha', 25)
print(egon)
print(nezh) # 会发现两个对象的内存地址一样
print(nezh.name)
print(egon.name)
print(nezh.cloth)
eq
class A:
def __init__(self, name) -> None:
self.name = name
def __eq__(self, other) -> bool: # 当没有__eq__时,默认对象比较是内存地址,有的时候写判断
if self.name == other.name:
return True
else:
return False
ob1 = A('egg')
ob2 = A('egg')
print(ob1 == ob2)
hash
class A:
def __init__(self, name, sex) -> None:
self.name = name
self.sex = sex
def __hash__(self) -> int: # 实现代替hash方法,先用自己的,相当于重写hash()
return hash(self.name+self.sex)
a = A('egg', '男')
b = A('egg', '男')
print(hash(a)) # 根据内存地址hash
print(hash(b))
纸牌游戏
# 创建没有方法只有属性的类,rank 牌面的大小,suit牌面的花色
Card = namedtuple('Card', ['rank', 'suit'])
# c1 =Card(2,'红心')
# print(c1)
# print(c1.suit)
class FranchDeck:
ranks = [str(n) for n in range(2, 11)] + list('JQKA')
suits = ['红心', '方板', '梅花', '黑桃']
def __init__(self):
self._cards = [Card(rank, suit) for rank in FranchDeck.ranks
for suit in FranchDeck.suits]
def __len__(self):
return len(self._cards)
def __getitem__(self, item):
return self._cards[item]
def __setitem__(self, key, value):
self._cards[key] = value
deck = FranchDeck()
print(deck[0])
print(choice(deck))
print(choice(deck)) # choice 依赖内置的__len__方法
shuffle(deck)
print(deck[:5]) # 切片,取前五个,deck可以切片是因为内置的方法
# n内置函数,内置的模块,内置的基础类型 都和类的内置方法有关
一道面试题
100个对象的类,名字和性别相同,年龄不同认为是同一个对象,去重
set方法
此方法set,依赖对象的hash方法和eq方法
class Person:
def __init__(self, name, age, sex):
self.name = name
self.age = age
self.sex = sex
def __hash__(self):
return hash(self.name+self.sex)
def __eq__(self, other):
if self.name == other.name and self.sex == other.sex:
return True
p_lst = []
for i in range(84):
p_lst.append(Person('egon', i, 'male'))
print(p_lst)
print(set(p_lst))
hashlib模块
用于登录认证的时候认证,使用摘要算法,两个字符串:有一个字符不一样就不同
md5 = hashlib.md5(bytes('salt', encoding='utf-8')) # 创建了一个md5的对象
md5.update(b'alex3714') # 必须是byte类型
print(md5.hexdigest()) # hexdigest拿到摘要算法的结果
# 摘要算法对同一个字符串进行摘要,结果不会变,摘要算法有很多种,最多的是md5,算法不同,功能相同
# 使用同一个算法得到的摘要的值是不变的,使用不同算法对不同字符串进行摘要,得到的值应该不同
# sha算法,复杂程度增加,时间成本,空间成本增加
# 应用于密码的密文存储,文件的一致性验证,两台机器上的两个文件是否相等
usr = input('usr')
pwd = input('pwd')
with open() 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('success')
else:
print('False')
# 网上的破解方法就是把所有的md5值存起来然后进行比对,叫撞库
# 加盐,可以增加一些安全性
md5 = hashlib.md5(bytes('salt', encoding='utf-8'))
md5.update(b'alex3714')
print(md5.hexdigest())
# 动态加盐 ,使用用户名的一部分或者整个用户名作为盐,一般不使用整个用户名作为盐
作业
对一个文件进行摘要算法,最后计算出这个文件的md5值

浙公网安备 33010602011771号