self 实例方法 ↙↙↙
class Gitee:def __repr__(self): # self 声明实例方法return "Gitee登录"class Ding:def __repr__(self):return "Ding登录"# 当打印实例对象的时候,打印的结果就是__repr__的返回值
@classmethod 类方法 ↙↙↙
class Book:def __init__(self, title):self.title = title# 声明类方法@classmethoddef create(cls, title):book = cls(title)return bookif __name__ == '__main__':book1 = Book('python')print(book1.title) # pythonbook2 = Book.create('python2')print(book2.title) # python2
@staticmethod 静态方法 ↙↙↙
# 简单工厂
class SimpleFactory:# 产品@staticmethoddef product(name):if name == "Gitee":return Gitee()else:return Ding()if __name__ == '__main__':product = SimpleFactory.product("Gitee")print(product) # Gitee登录print(Gitee()) # Gitee登录
抽象方法 @abstractmethod
目的:父类声明func()方法 继承类必须重写func()方法 ↙↙↙
# 抽象工厂模式
from abc import ABCMeta, abstractmethod# 声明元类
class TestMeta(metaclass=ABCMeta):def __init__(self):self.a = 1@abstractmethoddef func(self):pass
第一种:super() 调父类
第二种:TestMeta 调父类 ↙↙↙
class TestOne(TestMeta):def __init__(self):super().__init__() # 声明父类.init之后 不会覆盖父类init原有属性# TestMeta.__init__()self.b = 2# TestMeta重写抽象方法(@abstractmethod声明的抽象方法必须重写,不然报错)def func(self):print('马可波罗')a = TestOne()
print(a.a) # 输出父类TestMeta a属性的值 1
print(a.b) # 输出TestOne b属性的值 2
工厂流程
scripts文件 -> tests_factory.py
@abstractmethod 抽象工厂 ↙↙↙
(抽象类 父类)↙↙↙
class LoginProvider(metaclass=ABCMeta):# 跳转拼接url@abstractmethoddef get_url(self):pass# 获取token@abstractmethodasync def get_token(self, code):pass# 获取用户信息@abstractmethodasync def get_info(self, token):pass# 用户信息存储@abstractmethodasync def set_user(self, user):pass
(子类) ↙↙↙
class GiteeProvider(LoginProvider):def get_url(self):# 编写获取路由的代码 -> return返回对应的数据return '获取路由'# 获取tokenasync def get_token(self, code):# 编写获取token的代码 -> return返回对应的数据return '获取token'# 获取用户信息async def get_info(self, token):# 编写获取用户的代码 -> return返回对应的数据return '获取用户'# 用户信息存储async def set_user(self, user):# 编写创建用户的代码 -> return返回对应的数据return '创建用户'
(子类)Git三方登录方法 在视图Git三方登录中调用: 实例化Gitee类调用get方法即可生成用户token
from views.base import BaseHandlerclass Gitee(BaseHandler):def __init__(self, *args, **kwargs):super().__init__(*args, **kwargs)self.gitee = GiteeProvider()async def get(self):code = self.get_argument('code')# tokentoken = self.gitee.get_token(code)return token
Views视图文件
(父类)视图 base.py ↙↙↙
import json
import tornado.webclass BaseHandler(tornado.web.RequestHandler):# 通过继承父类tornado.web.RequestHandler 进行重写# 初始化方法(如果与父类方法重名,必须定义__init__方法,防止覆盖父类(finish与父类方法重名))def __init__(self, *args, **kwargs):tornado.web.RequestHandler.__init__(self, *args, **kwargs)def options(self):self.set_header(204)self.finish()# 跨域def set_default_headers(self):# 请求来源self.set_header('Access-Control-Allow-Origin', '*')# 请求方式self.set_header('Access-Control-Allow-Methods', 'POST,GET,PUT,DELETE,TRACE,HEAD,PATCH,OPTIONS')# 请求头self.set_header('Access-Control-Allow-Headers', '*')def finish(self, chunk=None):if chunk is not None and not isinstance(chunk, bytes):chunk = json.dumps(chunk, indent=4, sort_keys=True, default=str, ensure_ascii=False)try:tornado.web.RequestHandler.write(self, chunk)except Exception as e:passtornado.web.RequestHandler.finish(self)
********* 原Git三方登录
(子类)视图 user.py -> Gitee回调 ↙↙↙
import httpxclass GiteeBack(BaseHandler):async def get(self):code = self.get_argument("code", None)# ---------------------异步网络请求# 通过授权码请求tokenasync with httpx.AsyncClient() as client:res = await client.post(f"https://gitee.com/oauth/token?grant_type=authorization_code&code={code}&client_id={gitee_client_id}\&redirect_uri={gitee_redirect_url}&client_secret={gitee_client_secret}",timeout=20)# timeout 默认请求等待5秒data = json.loads(res.text)# tokenaccess_token = data['access_token']# refresh_token = data['refresh_token']# 通过token获取用户基本信息async with httpx.AsyncClient() as client:res2 = await client.get(f"https://gitee.com/api/v5/user?access_token={access_token}", timeout=20)user_info = json.loads(res2.text)if not user_info:return self.finish(({'code': 406, 'msg': '信息错误!'}))# gitee三方登录 id唯一 但用户名不唯一(采用id+用户名的方式存储数据库用户名)git_id = user_info['id'] # int类型git_name = user_info['name']git_username = str(git_id) + git_name# 通过gitee的id判断该用户gitee账号是否已经注册mj = MyJwt()try:info = await db.get(User.select().where((User.username == git_username) & (User.site_type == Site_type['Gitee']['num'])))except Exception as e:print(e)code4 = ''.join(random.sample(string.ascii_letters + string.digits, 4))pwd_new = md5_jm(code4)await db.create(User, username=git_username, password=pwd_new, site_type=Site_type['Gitee']['num'])info = await db.get(User.select().where((User.username == git_username) & (User.site_type == Site_type['Gitee']['num'])))token = mj.encode_date({'username': info.username, 'site_type': Site_type['Gitee']['num']})return self.redirect('http://127.0.0.1:8080/?username=' + git_name + '&token=' + token)# # -----------------------同步网络请求# # 通过授权码请求token# res = requests.post(# f"https://gitee.com/oauth/token?grant_type=authorization_code&code={code}\# &client_id={gitee_client_id}&redirect_uri={gitee_redirect_uri}&client_secret={gitee_client_secret}"# )# data = json.loads(res.text)## # token# access_token = data['access_token']# # refresh_token = data['refresh_token']## # 通过token获取用户基本信息# res2 = requests.get(f"https://gitee.com/api/v5/user?access_token={access_token}")# user_info = json.loads(res2.text)# # print(user_info)