Python实例方法,类方法,静态方法,抽象方法,GIT三方登录异步抽象工厂模式

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

    # 声明类方法
    @classmethod
    def create(cls, title):
        book = cls(title)
        return book


if __name__ == '__main__':
    book1 = Book('python')
    print(book1.title)        # python

    book2 = Book.create('python2')
    print(book2.title)        # python2

@staticmethod 声明静态方法 ↙↙↙ 

# 简单工厂
class SimpleFactory:
    # 产品
    @staticmethod
    def 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

    @abstractmethod
    def func(self):
        pass

第一种:super() 调父类

第二种:TestMeta 调父类 ↙↙↙

class TestOne(TestMeta):
    def __init__(self):
        super().__init__()
        # TestMeta.__init__()
        self.b = 2
        
        # 声明父类.__init__()之后 不会覆盖父类init原有属性

    # TestMeta重写抽象方法(@abstractmethod声明的抽象方法必须重写,不然报错)
    def func(self):
        print('马可波罗')


a = TestOne()
print(a.a)  # 输出父类TestMeta    a属性的值    1
print(a.b)  # 输出TestOne    b属性的值    2

在类中,调用异步方法 ↙↙

import asyncio


class A:
    async def get(self, id):
        data = {
            'git_id': 1,  # int类型
            'git_name': id,
            'git_username': '3'
        }
        return data

    async def bb(self):
        f = await self.get(5)
        print(type(f))      # dict
        print(f['git_name'])      # int 5

        # # 注:直接使用下面方法报错 ↙↙↙
        # f = await self.get(5)['git_name']
        # print(f)

        return 'grhtn'


if __name__ == '__main__':
    a = A()
    asyncio.run(a.bb())

异步GIT三方登录 抽象工厂模式 ↙↙↙

根目录创建scripts文件 -> tests_factory.py

导包

import json
import random
import string

import httpx    # 异步网络请求

# 三方登录需要的个人配置
from APP_ID import gitee_redirect_url, gitee_client_secret, gitee_client_id

# 异步链接 和 平台类型
from config import db, Site_type

from model.model import User

# jwt的封装
from utils.m_jwt import MyJwt

from utils.md5 import md5_jm

# 抽象类,抽象方法
from abc import ABCMeta, abstractmethod

使用 @abstractmethod方法 做一个抽象工厂 ↙↙↙

(抽象类 父类)↙↙↙ 
class LoginProvider(metaclass=ABCMeta):
    # 跳转拼接url
    @abstractmethod
    def get_url(self, code):
        pass

    # 获取access_token
    @abstractmethod
    async def get_token(self, url, code):
        pass

    # 获取用户信息
    @abstractmethod
    async def get_info(self, access_token):
        pass

    # 用户信息存储
    @abstractmethod
    async def set_user(self, access_token, git_info):
        pass

(子类) 
 Git三方登录封装方法↙↙↙ 
class GiteeProvider(LoginProvider):
    # 换code的地址
    def get_url(self, code):
        url = 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}"
        return url

    # 三方登录的token
    async def get_token(self, url, code):
        async with httpx.AsyncClient() as client:
            res = await client.post(
                url, timeout=20
            )
        # timeout 默认请求等待5秒
        data = json.loads(res.text)
        access_token = data['access_token']
        # refresh_token = data['refresh_token']
        return access_token

    # 获取用户信息
    async def get_info(self, access_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 '信息错误'
        # gitee三方登录 id唯一 但用户名不唯一(采用id+用户名的方式存储数据库用户名)
        git_info = {
            'git_id': user_info['id'],  # int类型
            'git_name': user_info['name'],
            'git_username': str(user_info['id']) + user_info['name']
        }
        return git_info

    # 用户信息存储
    async def set_user(self, access_token, git_info):
        # 通过gitee的id判断该用户gitee账号是否已经注册
        mj = MyJwt()
        try:
            user_info = await db.get(
                User.select().where((User.username == git_info['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_info['git_username'], password=pwd_new,
                            site_type=Site_type['Gitee']['num'])
            user_info = await db.get(
                User.select().where(
                    (User.username == git_info['git_username']) & (User.site_type == Site_type['Gitee']['num'])))
        token = mj.encode_date({'username': user_info.username, 'site_type': Site_type['Gitee']['num']})
        return 'http://127.0.0.1:8080/?username=' + git_info['git_username'] + '&token=' + token

根目录下的Views文件

(父类)视图 base.py ↙↙↙ 
# 基础视图
import json

import tornado.web


# 视图

class BaseHandler(tornado.web.RequestHandler):
    # 通过继承父类tornado.web.RequestHandler 进行重写
    # 初始化方法(如果与父类方法重名,必须定义__init__方法,防止覆盖父类(finish与父类方法重名))
    def __init__(self, *args, **kwargs):
        tornado.web.RequestHandler.__init__(self, *args, **kwargs)

    # 跨域
    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 options(self):
        self.set_status(204)
        self.finish()

    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:
            pass
        tornado.web.RequestHandler.finish(self)

    

(子类)视图 user.py -> Gitee回调 ↙↙↙   
class GiteeBack(BaseHandler):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.gitee = GiteeProvider()

    async def get(self):
        code = self.get_argument('code')
        url = self.gitee.get_url(code)
        access_token = await self.gitee.get_token(url, code)
        git_info = await self.gitee.get_info(access_token)
        redirect_url = await self.gitee.set_user(access_token, git_info)
        return self.redirect(redirect_url)

你可能感兴趣的:(Python,python,开发语言)