22 元类技术(面向切片编程)|ORM的实现|抽象类与接口类
文章目录
- 前情知识补充
- hasattr 函数
- setattr函数
- getattr函数
- join 函数
- 元类技术
- 使用type创建类
- 什么是元类(概念总结)
- \_\_metaclass\_\_属性
- 使用metaclass 的函数方式进行创建类
- 使用metaclass 的类方式进行创建类
- 自定义元类
- 元类实现ORM
- 接口类与抽象类
- 抽象类
- 接口类
- 注意点
前情知识补充
hasattr 函数
class ObjectCreator(object):passmy_object = ObjectCreator()# hasattr用来判断一个对象是否有某个属性,有就是True,没有就是false
print(hasattr(ObjectCreator, 'new_attribute'))ObjectCreator.new_attribute = 'foo' # 你可以为类增加属性print(hasattr(ObjectCreator, 'new_attribute'))
输出:

setattr函数
这个函数是用来给对象赋属性以及对应的值的
使用的方式:
setattr(object 对象, name 字符串 对象属性, value 属性的值)
>>>class A(object):
... bar = 1
...
>>> a = A()
>>> getattr(a, 'bar') # 获取属性 bar 值
1
>>> setattr(a, 'bar', 5) # 设置属性 bar 值
>>> a.bar
5
getattr函数
参考链接
基本使用方式
getattr(object 对象, name 对象属性, default 如果不存在则返回的值)
一般用于由用户或者程序自动决定想要访问的属性名时,采用这种方法,并且省去try的异常检测,直接自定义返回值。
样例:
from typing import NamedTupleclass Person(NamedTuple):'''人类'''name: strage: intjob: strweight: floatheight: floatalex = Person('Alex', 32, 'actor', 60, 178)# 把用户输入的字符串赋值给变量attribute_name
attribute_name = input('''What do you want to know about Alex?
Enter an attribute name>>>''')
# 注意,上述字符串被传进了这个函数作为第二个参数
# 第三个参数是属性不存在时返回的字符串
print(getattr(alex,attribute_name, 'Sorry, this attribute does not exist.'))
join 函数
参考链接链接
这边只介绍元组:
tuple1 = ('a','b','c') #定义元组tuple1
'、'.join(tuple1)
输出: a、b、ctuple2 = ('hello','peace','world') #定义元组tuple2
' '.join(tuple2)
输出:hello peace world
元类技术
先介绍方法,再去介绍相关的概念,感觉比较好理解
使用type创建类
先是关于type的基础介绍:
创建出来的类名称 = type("创建出来的类名称", (元组内部放想要继承的类,), {"print_b": print_b, 字典放类函数})
样例见下:
class A(object):num = 100def print_b(self):print(self.num)@staticmethod
def print_static():print("----haha-----")@classmethod
def print_class(cls):print(cls.num)B = type("B", (A,), {"print_b": print_b, "print_static": print_static,"print_class": print_class})
b = B()
b.print_b()
b.print_static()
b.print_class()
什么是元类(概念总结)
这是因为函数 type 实际上是一个元类。type 就是 Python 在背后用来创建所有类的元类。跟int 一样之所以type全是小写,就是根据于此,int是用来创建整形的变量,type就是用来创建类的类。
__metaclass__属性
python在创建类的时候会经过下面的步骤:
- 类 中有__metaclass__这个属性吗?如果是,Python 会通过__metaclass__创建
- 如果 Python 没有找到__metaclass__,它会继续在 父类中寻找
__metaclass__属性,并尝试做和前面同样的操作。 - 如果 Python 在任何父类中都找不到__metaclass__,它就会在模块层次中去寻找__metaclass__,并尝试做同样的操作。
- 如果还是找不到__metaclass__,Python 就会用内置的 type 来创建这个类对象
使用metaclass 的函数方式进行创建类
def upper_class(class_name, class_parent, class_function: dict):"""这边实现的就是将类元素全部变成大写的"""new_dict = dict()for key, function in class_function.items():if not key.startswith('__'):new_dict[key.upper()] = functionreturn type(class_name, class_parent, new_dict)class Test(object, metaclass=upper_class):a = 1print(Test.a)
print(Test.A)

输出的结果:

使用metaclass 的类方式进行创建类
class UpperAttrMetaClass(type):# __new__ 是在__init__之前被调用的特殊方法# __new__是用来创建对象并返回之的方法# 而__init__只是用来将传入的参数初始化给对象# 你很少用到__new__,除非你希望能够控制对象的创建# 这里,创建的对象是类,我们希望能够自定义它,所以我们这里改写__new__# 如果你希望的话,你也可以在__init__中做些事情# 还有一些高级的用法会涉及到改写__call__特殊方法,但是我们这里不用def __new__(cls, class_name, class_parents, class_attr):# 遍历属性字典,把不是__开头的属性名字变为大写new_attr = {}for name, value in class_attr.items():if not name.startswith("__"):new_attr[name.upper()] = value# 值得关注的是需要用这种形式type.__new__而不是使用 type()return type.__new__(cls, class_name, class_parents, new_attr)# python3的用法
class Foo(object, metaclass=UpperAttrMetaClass):bar = 'bip'print(Foo.BAR)
使用type.__new__而不使用type的原因:链接
自定义元类
正常人不需要,只有在想要看懂框架,特别是深度学习的时候需要搞懂这门技术,自己也不需要这么写OxO
“元类就是深度的魔法,99%的用户应该根本不必为此操心。如果你想搞清楚究竟是否需要用到元类,那么你就不需要它。那些实际用到元类的人都非常清楚地知道他们需要做什么,而且根本不需要解释为什么要用元类。” —— Python 界的领袖 Tim Peter”
元类实现ORM
class ModelMetaclass(type):def __new__(cls, name, bases, attrs):mappings = dict()# 判断是否需要保存for k, v in attrs.items():# 判断是否是指定的StringField或者IntegerField的实例对象if isinstance(v, tuple):print('Found mapping: %s ==> %s' % (k, v))mappings[k] = v# 删除这些已经在字典中存储的属性for k in mappings.keys():attrs.pop(k)# if name == 'User':# attrs.pop('hello')# 将之前的uid/name/email/password以及对应的对象引用、类名字attrs['__mappings__'] = mappings # 保存属性和列的映射关系attrs['__table__'] = name # 假设表名和类名一致return super().__new__(cls, name, bases, attrs)class Model(object, metaclass=ModelMetaclass):def __init__(self, **kwargs):for name, value in kwargs.items():setattr(self, name, value)def save(self):fields = []args = []for k, v in self.__mappings__.items():fields.append(v[0])args.append(getattr(self, k, None))args_temp = list()for temp in args:# 判断入如果是数字类型if isinstance(temp, int):args_temp.append(str(temp))elif isinstance(temp, str):args_temp.append("""'%s'""" % temp)sql = 'insert into %s (%s) values (%s)' % (self.__table__, ','.join(fields), ','.join(args_temp))print('SQL: %s' % sql)class User(Model):uid = ('uid', "int unsigned")name = ('username', "varchar(30)")email = ('email', "varchar(30)")password = ('password', "varchar(30)")u = User(uid=12345, name='Michael', email='test@orm.org', password='my-pwd')
print(u.__dict__)
u.save()
建议一步一步调试看看函数的执行流程。
接口类与抽象类
抽象类的定义就是:作为微信支付宝的父类,定义了一个具有支付功能的设计类,但是又没有具体实现,需要子类去实现具体的功能的一种类。
接口类的定义就是:一个接口就是一个类,在这个类当中,我们尽量希望有少 或者 仅有一个方法,也即方法即类,在后面使用的时候,我们使用一个子类去继承一个个接口类,并且都将其实例化到各个类代码当中。
二者使用的场景不同:抽象类希望的是本身具有越多的属性越好,然后子类继承,实例化即可,而接口类希望的是本身方法越少越好,最好自己就是一个行为。
抽象类
同样也需要用到元类技术metaclass,以及需要额外导入一个包:
“from abc import abstractmethod, ABCMeta” 使用内部的装饰器@abstractmethod即可创建出一个抽象属性(意思就是子类需要将其定义其功能,而自己只需要写个名字)
from abc import abstractmethod, ABCMeta# 使用了抽象方法的类,就是抽象类,Payment就是一个抽象类
class Payment(metaclass=ABCMeta):@abstractmethoddef pay(self, money):passclass Alipay(Payment):def pay(self, money): # 这里类的方法不是一致的pay,导致后面调用的时候找不到payprint('支付宝支付了')# 如果子类中没有实现抽象方法,实例化对象时,就会报错
p = Alipay()
接口类
from abc import abstractmethod, ABCMetaclass WalkAnimal(metaclass=ABCMeta):@abstractmethoddef walk(self):passclass SwimAnimal(metaclass=ABCMeta):@abstractmethoddef swim(self):passclass FlyAnimal(metaclass=ABCMeta):@abstractmethoddef fly(self):pass# 如果正常一个老虎有跑和跑的方法的话,我们会这么做
class Tiger(WalkAnimal, SwimAnimal):def walk(self): passdef swim(self): passt = Tiger()
如上,就不进行解释了。
注意点
注意点:
- 抽象类是一个介于类和接口之间的一个概念,同时具备类和接口的部分特性,可以用来实现归一化设计。
- 在继承抽象类的过程中,我们应该尽量避免多继承;
- 而在继承接口的时候,我们反而鼓励你来多继承接口, 一般情况下 单继承 能实现的功能都是一样的,所以在父类中可以有一些简单的基础实现,多继承的情况 由于功能比较复杂,所以不容易抽象出相同的功能的具体实现写在父类中。
相关文章:
22 元类技术(面向切片编程)|ORM的实现|抽象类与接口类
文章目录 前情知识补充hasattr 函数setattr函数getattr函数join 函数 元类技术使用type创建类什么是元类(概念总结)\_\_metaclass\_\_属性使用metaclass 的函数方式进行创建类使用metaclass 的类方式进行创建类 自定义元类 元类实现ORM接口类与抽象类抽象…...
fuchsia系统介绍
fuchsia系统 Fuchsia,是由Google公司开发的继Android和Chrome OS之后的第三个系统,已在Github中公开的部分源码可以得知。Google对于Fuchsia的说明是“Pink(粉红)Purple(紫色)Fuchsia(灯笼海棠…...
解决Jenkins执行Python脚本不能实时输出打印信息的问题
问题: 在使用Jenkins的shell command来执行python脚本时,总是会等脚本执行完毕,最后一次性才把脚本中的print语句给打印出来; 解决方法: 在print语句后加上sys.stdout.flush(), 就可以达到实时输出的目的了。...
2021年03月 C/C++(五级)真题解析#中国电子学会#全国青少年软件编程等级考试
C/C++编程(1~8级)全部真题・点这里 第1题:最小新整数 给定一个十进制正整数n(0 < n < 1000000000),每个数位上数字均不为0。n的位数为m。 现在从m位中删除k位(0<k < m),求生成的新整数最小为多少? 例如: n = 9128456, k = 2, 则生成的新整数最小为12456 时间…...
【微服务】服务发现和管理技术框架选型调研
选型背景 方案对比 结论 结合实际业务和开发需要,着重考虑性能可靠性、功能和社区支持程度三方面,认为Nacos更适合作为服务发现和管理的技术框架。具体理由如下: 性能更好,可靠性更高 经过阿里、APISIX、SpringCloudAlibaba,阿…...
【核磁共振成像】观共享重建
目录 一、K空间关键孔技术-数据采集二、BRISK技术三、TRICKS技术四、实时成像和滑动窗重建五、心电触发电影(CINE)采集六、分段心脏采集和观共享 一、K空间关键孔技术-数据采集 对于笛卡尔K空间,一个相位编码行有时称为一个K空间观。一般情况下,每帧图像…...
〔020〕Stable Diffusion 之 骨骼姿势 篇
✨ 目录 🎈 姿势检测 / OpenPose🎈 姿势检测 OpenPose 参数介绍🎈 姿势检测 OpenPose 基本使用🎈 深度库 / Depth Lib🎈 深度库 Depth Lib 参数介绍🎈 3D姿势检测 / 3D Openpose Editor🎈 3D姿势检测 3D Openpose Editor 参数介绍🎈 3D姿势检测 3D Openpose Ed…...
使用Python进行Base64编码和解码
假设您有一个想要通过网络传输的二进制图像文件。您很惊讶对方没有正确接收该文件 - 该文件只是包含奇怪的字符! 嗯,您似乎试图以原始位和字节格式发送文件,而所使用的媒体是为流文本而设计的。 避免此类问题的解决方法是什么?答…...
MongoDB的数据恢复与备份
MongoDB的数据恢复与备份 在MongoDB中,备份和恢复数据是一项关键任务,可以确保数据的安全性并防止意外数据丢失。本文将介绍MongoDB的数据恢复与备份原理并提供相关的编程代码和配置。 1. 数据备份原理 MongoDB提供了多种备份数据…...
Java之SpringCloud Alibaba【五】【微服务 Sentinel整合openfeign进行降级】
一、Sentinel整合openfeign 1、复制一下order-openfeign项目(创建order-openfeign-sentinel) 然后在stock-nacos当中编写对应的接口 RequestMapping("/reduct2")public String reduct2(){int a 1/0;System.out.println("扣减库存"…...
电脑前置耳机没声音怎么办
有很多小伙伴反映在将自己的耳机连接到主机前面时没有声音,这是怎么回事呢,遇到这种情况应该怎么解决呢,下面小编就给大家详细介绍一下电脑前置耳机没声音的解决方法,有需要的小伙伴可以来看一看电脑前面耳机没声音。 解决方法&a…...
package.json 详解
文章目录 package.json1. name2. version3. description4. homepage5. bugs6. license7. author, contributors8. funding9. files10. main11. module12. browser13. bin14. man15. directories15.1 directories.bin15.2 directories.man 16. repository17. scripts18. config1…...
springboot配置ym管理各种日记(log)
1:yml配置mybatis_plus默认日记框架 mybatis-plus:#这个作用是扫描xml文件生效可以和mapper接口文件使用,#如果不加这个,就无法使用xml里面的sql语句#启动类加了MapperScan是扫描指定包下mapper接口生效,如果不用MapperScan可以在每一个mapp…...
你知道Vue 3.0中Treeshaking特性吗?
介绍 Vue 3.0引入了Tree-shaking特性,旨在优化构建过程并减小最终生成的代码大小。Tree-shaking是一种在构建时移除未使用代码的技术,通过分析模块的依赖关系,将没有被引用的部分从最终的打包文件中排除掉。这可以大大减少应用的体积&#x…...
TP6 开启关闭debug
config 不起作用,还得来这里改: 或者单个方法里加: $this->app->debug(true); //临时错误调试...
Linux centos7 bash编程(break和continue)
在学习shell知识时,简单编程要从格式入手。 首先学习好单行注释和多行注释。 先学习简单整数的打印输出,主要学习echo命令,学习选项-e -n的使用。 下面的练习是常用的两个分支跳转程序:break和continue。 #!/bin/bash # 这是单…...
【论文精读AAAI_2022】MobileFaceSwap: A Lightweight Framework for Video Face Swapping
【论文精读AAAI_2022】MobileFaceSwap: A Lightweight Framework for Video Face Swapping 一、前言AbstractIntroductionRelated WorkFace swapping.Dynamic neural networks.Knowledge distillation.MethodNetwork ArchitectureTraining ObjectivesExperimentsQualitative Re…...
rust中使用sqlite 之 rusqlite使用
名称版本rusqlite0.29.0impl From<&rusqlite::Row<_>> for Person {fn from(r: &rusqlite...
Linux系统Ubuntu配置Docker详细流程
本文介绍在Linux操作系统Ubuntu的18.04及以上版本中,配置开源容器化平台和工具集Docker的详细方法;其中,我们以配置Docker平台的核心组件之一——Docker Engine为例来详细介绍。 首先,大家需要明确,我们常说的Docker&a…...
能直接运营的发接任务平台小程序搭建开发演示
有个项目估计做过互联网的小伙伴都听说过——发接任务平台。 基本每年都有发接任务平台关站,但又有新的平台出来,往复循环,无比热闹。这在互联网圈不常见,互联网项目很多都是风头过去了就结束了,但发接任务年年似乎都…...
模型参数、模型存储精度、参数与显存
模型参数量衡量单位 M:百万(Million) B:十亿(Billion) 1 B 1000 M 1B 1000M 1B1000M 参数存储精度 模型参数是固定的,但是一个参数所表示多少字节不一定,需要看这个参数以什么…...
【2025年】解决Burpsuite抓不到https包的问题
环境:windows11 burpsuite:2025.5 在抓取https网站时,burpsuite抓取不到https数据包,只显示: 解决该问题只需如下三个步骤: 1、浏览器中访问 http://burp 2、下载 CA certificate 证书 3、在设置--隐私与安全--…...
华硕a豆14 Air香氛版,美学与科技的馨香融合
在快节奏的现代生活中,我们渴望一个能激发创想、愉悦感官的工作与生活伙伴,它不仅是冰冷的科技工具,更能触动我们内心深处的细腻情感。正是在这样的期许下,华硕a豆14 Air香氛版翩然而至,它以一种前所未有的方式&#x…...
云原生安全实战:API网关Kong的鉴权与限流详解
🔥「炎码工坊」技术弹药已装填! 点击关注 → 解锁工业级干货【工具实测|项目避坑|源码燃烧指南】 一、基础概念 1. API网关(API Gateway) API网关是微服务架构中的核心组件,负责统一管理所有API的流量入口。它像一座…...
PHP 8.5 即将发布:管道操作符、强力调试
前不久,PHP宣布了即将在 2025 年 11 月 20 日 正式发布的 PHP 8.5!作为 PHP 语言的又一次重要迭代,PHP 8.5 承诺带来一系列旨在提升代码可读性、健壮性以及开发者效率的改进。而更令人兴奋的是,借助强大的本地开发环境 ServBay&am…...
论文阅读笔记——Muffin: Testing Deep Learning Libraries via Neural Architecture Fuzzing
Muffin 论文 现有方法 CRADLE 和 LEMON,依赖模型推理阶段输出进行差分测试,但在训练阶段是不可行的,因为训练阶段直到最后才有固定输出,中间过程是不断变化的。API 库覆盖低,因为各个 API 都是在各种具体场景下使用。…...
[论文阅读]TrustRAG: Enhancing Robustness and Trustworthiness in RAG
TrustRAG: Enhancing Robustness and Trustworthiness in RAG [2501.00879] TrustRAG: Enhancing Robustness and Trustworthiness in Retrieval-Augmented Generation 代码:HuichiZhou/TrustRAG: Code for "TrustRAG: Enhancing Robustness and Trustworthin…...
区块链技术概述
区块链技术是一种去中心化、分布式账本技术,通过密码学、共识机制和智能合约等核心组件,实现数据不可篡改、透明可追溯的系统。 一、核心技术 1. 去中心化 特点:数据存储在网络中的多个节点(计算机),而非…...
React从基础入门到高级实战:React 实战项目 - 项目五:微前端与模块化架构
React 实战项目:微前端与模块化架构 欢迎来到 React 开发教程专栏 的第 30 篇!在前 29 篇文章中,我们从 React 的基础概念逐步深入到高级技巧,涵盖了组件设计、状态管理、路由配置、性能优化和企业级应用等核心内容。这一次&…...
如何做好一份技术文档?从规划到实践的完整指南
如何做好一份技术文档?从规划到实践的完整指南 🌟 嗨,我是IRpickstars! 🌌 总有一行代码,能点亮万千星辰。 🔍 在技术的宇宙中,我愿做永不停歇的探索者。 ✨ 用代码丈量世界&…...
