关于注册和登录的各有一个问题
- 注册方面:
1.1 为什么注册之前要先实例化一个user才可以注册新用户(如user.py中的入口函数)?这样不就变成只有role是admin的人才有权限新建用户吗? - 登录方面:
2.1 为什么登录也是需要先实例化一个人才能登录,不是跟正常逻辑有出入吗?
我目前尝试过使用classmethod来登录,但是由于少参数,而无法登录。
下面是我写的代码,请老师指点迷津。
# coding: utf-8
import os
import random
import hashlib
from base import Base
from common.utils import timestamp_to_string
from common.error import (NotUserError, RoleError,
CountError, UserActiveError)
class User(Base):
def __init__(self, username, user_json, gift_json):
self.username = username
self.gift_random = list(range(1,100))
super().__init__(user_json, gift_json)
self.get_user()
def get_user(self):
users = self._Base__read_users()
if self.username not in users:
raise NotUserError('not user %s' % self.username)
current_user = users.get(self.username)
# 对比密码 json_password数据库中的密码,u_password用户输入的密码
json_password = current_user.get('password') # 16进制格式
_password = self.password
u_password = hashlib.sha1(_password.encode('utf-8')).hexdigest()
if u_password != json_password:
print('密码错误')
return
if current_user.get('active') == False:
raise UserActiveError('%s is not active' % self.username)
if current_user.get('role') != 'admin':
raise RoleError('Not Admin')
self.user = current_user
self.name = current_user.get('username')
self.role = current_user.get('role')
self.gifts = current_user.get('gifts')
self.create_time = timestamp_to_string(current_user.get('create_time'))
# 用户注册函数
def register(self, username, password):
# 存储用户信息
self._Base__write_user(username=username,
role='normal',
password=password)
def login(self):
username = input('please enter your username:')
password = input('please enter your password:')
self.get_user(username=username,password=password)
def get_gift(self):
gifts = self._Base__read_gifts()
gift_lists = []
for level_one, level_one_pool in gifts.items(): # key, value
for level_two, level_two_pool in level_one_pool.items():
for gift_name, gift_info in level_two_pool.items():
gift_lists.append(gift_info.get('name'))
return gift_lists
# 用户抽奖函数user.py中的choice_gift函数,当抽中函数后,实现了对相关奖品进行减少数量的操作,
# 用base.py中__gift_update函数替代choice_gift中的功能。
def choice_gift(self):
self.get_user()
# level1 get
first_level, second_level = None, None
# 抽第一级目录
level_one_count = random.choice(self.gift_random)
if 1 <= level_one_count <= 50:
first_level = 'level1'
elif 51 <= level_one_count <= 80:
first_level = 'level2'
elif 81 <= level_one_count < 95:
first_level = 'level3'
elif level_one_count >= 95:
first_level = 'level4'
else:
raise CountError('level_one_count need 0~100')
# 获取第一级清单
gifts = self._Base__read_gifts()
level_one = gifts.get(first_level)
# 抽第二级目录
level_two_count = random.choice(self.gift_random)
if 1 <= level_two_count <= 80:
second_level = 'level1'
elif 81 <= level_two_count < 95:
second_level = 'level2'
elif 95 <= level_two_count <= 100:
second_level = 'level3'
else:
raise CountError('level_one_count need 0~100')
# 获取第二级清单
level_two = level_one.get(second_level)
if len(level_two) == 0:
print("可惜,您没有中奖")
return
# 以列表的方式获取到奖品信息
gift_names = []
for k, _ in level_two.items(): # 忽略count,以_代替
gift_names.append(k)
gift_name = random.choice(gift_names)
# 使用gift_update来替代自己写的函数
self._Base__gift_update(first_level, second_level, gift_name)
# 提示用户中奖了
print('恭喜您,获得了 %s 奖品' % gift_name)
def update(self):
users = self._Base__read_users()
users[self.username] = self.user
self._Base__save(users, self.user_json)
if __name__ == "__main__":
gift_path = os.path.join(os.getcwd(), 'storage', 'gift.json')
user_path = os.path.join(os.getcwd(), 'storage', 'user.json')
user = User('dewei', user_path, gift_path)
user.register(username='xuhaoyan',password='xhy123123')
# coding: utf-8
import os
import json
import time
import hashlib
import multiprocessing
from common.utils import check_file, timestamp_to_string
from common.error import (UserExistsError, RoleError,
LevelError, NegativeNumberError, CountError) # 用户存在报错提示
from common.consts import ROLES, FIRSTLEVELS, SECONDLEVELS
class Base(object):
def __init__(self, user_json, gift_json):
self.user_json = user_json
self.gift_json = gift_json
self.__check_user_json()
self.__check_gift_json()
self.__init_gifts()
# 防止并发思路:在对user.json, gift.json两个文件的删除,
# 修改以及添加三个相关函数并添加进程锁,从而防止并发。
manager = multiprocessing.Manager()
self.lock = manager.Lock()
def __check_user_json(self):
check_file(self.user_json)
def __check_gift_json(self):
check_file(self.gift_json)
def __read_users(self, time_to_str=False):
with open(self.user_json, 'r') as f:
data = json.loads(f.read())
if time_to_str == True:
for username, v in data.items():
v['create_time'] = timestamp_to_string(v['create_time'])
v['update_time'] = timestamp_to_string(v['update_time'])
data[username] = v
return data # 返回的应该是字典类型的数据
# 创建用户信息
def __write_user(self, **user):
if 'username' not in user:
raise ValueError('missing username')
if 'role' not in user:
raise ValueError('missing role')
# 以hashlib的方式存入密码
# 对password进行比特类型转encode
hashcode = hashlib.sha1(user['password'].encode('utf-8'))
# 生成16进制加密串
_token = hashcode.hexdigest()
# user['active'] = True
user['active'] = False
user['create_time'] = time.time()
user['update_time'] = time.time()
user['gifts'] = []
user['password'] = _token
users = self.__read_users()
if user['username'] in users:
raise UserExistsError('username %s 已存在' % user['username'])
users.update(
{user['username']: user} # {'dewei':{username:...}}
)
self.__save(users, self.user_json)
# json_users = json.dumps(users)
# with open(self.user_json, 'w') as f:
# f.write(json_users)
def __change_role(self, username, role):
users = self.__read_users()
user = users.get(username)
if not user:
return False
if role not in ROLES:
raise RoleError('not user role %s' % role)
user['role'] = role # 不能随便修改
user['update_time'] = time.time()
users[username] = user
self.__save(users, self.user_json)
def __change_active(self, username):
users = self.__read_users()
user = users.get(username)
if not user:
return False
user['active'] = not user['active']
user['update_time'] = time.time()
users[username] = user
self.__save(users, self.user_json)
return True
def __delete_user(self, username):
users = self.__read_users()
user = users.get(username)
if not user:
return False
delete_user = users.pop(username)
self.__save(users, self.user_json)
return delete_user
def __read_gifts(self):
with open(self.gift_json) as f:
data = json.loads(f.read())
return data
def __init_gifts(self):
data = {
'level1':{
'level1':{},
'level2':{},
'level3':{}
},
'level2': {
'level1': {},
'level2': {},
'level3': {}
},
'level3': {
'level1': {},
'level2': {},
'level3': {}
},
'level4': {
'level1': {},
'level2': {},
'level3': {}
}
}
gifts = self.__read_gifts()
if len(gifts) != 0:
return
self.__save(data, self.gift_json)
def __check_and_getgift(self, first_level, second_level, gift_name):
if first_level not in FIRSTLEVELS:
raise LevelError('firstlevel does not exist')
if second_level not in SECONDLEVELS:
raise LevelError('secondlevel does not exist')
gifts = self.__read_gifts()
level_one = gifts[first_level] # 获取了level1的level
level_two = level_one[second_level]
if gift_name not in level_two:
return False
return{
'level_one': level_one,
'level_two': level_two,
'gifts': gifts
}
def __write_gifts(self, first_level, second_level,
gift_name, gift_count):
if first_level not in FIRSTLEVELS:
raise LevelError('firstlevel does not exist')
if second_level not in SECONDLEVELS:
raise LevelError('secondlevel does not exist')
gifts = self.__read_gifts()
current_gift_pool = gifts[first_level]
current_second_gift_pool = current_gift_pool[second_level]
if gift_count <= 0:
gift_count = 1
if gift_name in current_second_gift_pool:
current_second_gift_pool[gift_name]['count'] = \
current_second_gift_pool[gift_name]['count'] + gift_count
else:
current_second_gift_pool[gift_name] = {
'name': gift_name,
'count': gift_count
}
gifts[first_level] = current_gift_pool
current_gift_pool[second_level] = current_second_gift_pool
self.__save(gifts, self.gift_json)
def __gift_update(self, first_level, second_level,
gift_name, gift_count=1, is_admin=False):
assert isinstance(gift_count, int), 'gift count is an int'
data = self.__check_and_getgift(first_level, second_level, gift_name)
if data == False:
return data
current_gift_pool = data.get('level_one')
current_second_gift_pool = data.get('level_two')
gifts = data.get('gifts')
if gift_name not in current_second_gift_pool:
return False
current_gift = current_second_gift_pool[gift_name]
# 判断用户是不是admin权限
if is_admin == True:
if gift_count <= 0:
# raise CountError('gift_count can not be zero')
print('可惜,奖品没有了')
current_gift['count'] = gift_count
else:
if current_gift['count'] - gift_count< 0:
return NegativeNumberError('gift count can not be negative')
current_gift['count'] -= gift_count
# 奖品数量变动后,将整个字典传入
current_second_gift_pool[gift_name] = current_gift
current_gift_pool[second_level] = current_second_gift_pool
gifts[first_level] = current_gift_pool
self.__save(gifts, self.gift_json)
def __delete_gift(self, first_level, second_level, gift_name):
data = self.__check_and_getgift(first_level, second_level, gift_name)
if data == False:
return data
current_gift_pool = data.get('level_one')
current_second_gift_pool = data.get('level_two')
gifts = data.get('gifts')
delete_gift_data = current_second_gift_pool.pop(gift_name)
current_gift_pool[second_level] = current_second_gift_pool
gifts[first_level] = current_gift_pool
self.__save(gifts, self.gift_json)
return delete_gift_data
def __save(self, data, path):
json_data = json.dumps(data)
# 创建锁,防止并发,最后无论如何锁打开
try:
self.lock.acquire()
with open(path, 'w') as f:
f.write(json_data)
finally:
self.lock.release()
14
收起
正在回答 回答被采纳积分+1
1回答
好帮手慕燕燕
2021-04-09 16:49:28
同学,你好!
1、注册用户并非要先实例化一个user类,可以自定义一个用户注册类RegistUser类,实现用户注册功能,并不是要求角色为admin的人新建用户,同学可参考以下代码:
2、User类的init方法中调用了get_user()方法,实例化User类,类中的init方法被自动执行,也就执行了里面的get_user()方法,而get_user()方法实现用户的登录功能,因此登录要先实例化User类
3、同学的User类init方法缺少password参数,判断密码时使用self.password会提示缺少参数
4、判断密码可参考以下写法:
5、实例化User类时也需要传入密码
祝:学习愉快!
Python全栈工程师2020
- 参与学习 人
- 提交作业 5211 份
- 解答问题 2433 个
Facebook曾声称“只招全栈工程师”!全栈用人需求猛增,市面人才紧缺。 0基础进击Python全栈开发,诱人薪资在前方!
了解课程
恭喜解决一个难题,获得1积分~
来为老师/同学的回答评分吧
0 星