Python如何定义有可选参数的元类


Posted in Python onJuly 31, 2020

问题

你想定义一个元类,允许类定义时提供可选参数,这样可以控制或配置类型的创建过程。

解决方案

在定义类的时候,Python允许我们使用 ``metaclass``关键字参数来指定特定的元类。 例如使用抽象基类:

from abc import ABCMeta, abstractmethod
class IStream(metaclass=ABCMeta):
  @abstractmethod
  def read(self, maxsize=None):
    pass

  @abstractmethod
  def write(self, data):
    pass

然而,在自定义元类中我们还可以提供其他的关键字参数,如下所示:

class Spam(metaclass=MyMeta, debug=True, synchronize=True):
  pass

为了使元类支持这些关键字参数,你必须确保在 __prepare__() , __new__() __init__() 方法中 都使用强制关键字参数。就像下面这样:

class MyMeta(type):
  # Optional
  @classmethod
  def __prepare__(cls, name, bases, *, debug=False, synchronize=False):
    # Custom processing
    pass
    return super().__prepare__(name, bases)

  # Required
  def __new__(cls, name, bases, ns, *, debug=False, synchronize=False):
    # Custom processing
    pass
    return super().__new__(cls, name, bases, ns)

  # Required
  def __init__(self, name, bases, ns, *, debug=False, synchronize=False):
    # Custom processing
    pass
    super().__init__(name, bases, ns)

讨论

给一个元类添加可选关键字参数需要你完全弄懂类创建的所有步骤, 因为这些参数会被传递给每一个相关的方法。 __prepare__() 方法在所有类定义开始执行前首先被调用,用来创建类命名空间。 通常来讲,这个方法只是简单的返回一个字典或其他映射对象。 __new__() 方法被用来实例化最终的类对象。它在类的主体被执行完后开始执行。 __init__() 方法最后被调用,用来执行其他的一些初始化工作。

当我们构造元类的时候,通常只需要定义一个 __new__() __init__() 方法,但不是两个都定义。 但是,如果需要接受其他的关键字参数的话,这两个方法就要同时提供,并且都要提供对应的参数签名。 默认的 __prepare__() 方法接受任意的关键字参数,但是会忽略它们, 所以只有当这些额外的参数可能会影响到类命名空间的创建时你才需要去定义 __prepare__() 方法。

通过使用强制关键字参数,在类的创建过程中我们必须通过关键字来指定这些参数。

使用关键字参数配置一个元类还可以视作对类变量的一种替代方式。例如:

class Spam(metaclass=MyMeta):
  debug = True
  synchronize = True
  pass

将这些属性定义为参数的好处在于它们不会污染类的名称空间, 这些属性仅仅只从属于类的创建阶段,而不是类中的语句执行阶段。 另外,它们在 __prepare__() 方法中是可以被访问的,因为这个方法会在所有类主体执行前被执行。 但是类变量只能在元类的 __new__()__init__() 方法中可见。

以上就是Python如何定义有可选参数的元类的详细内容,更多关于Python定义元类的资料请关注三水点靠木其它相关文章!

Python 相关文章推荐
Windows和Linux下Python输出彩色文字的方法教程
May 02 Python
numpy中索引和切片详解
Dec 15 Python
python中map的基本用法示例
Sep 10 Python
对python多线程与global变量详解
Nov 09 Python
python判断文件夹内是否存在指定后缀文件的实例
Jun 10 Python
Python使用itchat模块实现群聊转发,自动回复功能示例
Aug 26 Python
Pytorch训练过程出现nan的解决方式
Jan 02 Python
OpenCV中VideoCapture类的使用详解
Feb 14 Python
Python3.9 beta2版本发布了,看看这7个新的PEP都是什么
Jun 10 Python
Python Tornado核心及相关原理详解
Jun 24 Python
Python编解码问题及文本文件处理方法详解
Jun 20 Python
python中的getter与setter你了解吗
Mar 24 Python
Python爬虫爬取糗事百科段子实例分享
Jul 31 #Python
Python如何对齐字符串
Jul 30 #Python
Python3爬虫关于代理池的维护详解
Jul 30 #Python
Python读写压缩文件的方法
Jul 30 #Python
Python3爬虫里关于代理的设置总结
Jul 30 #Python
Python 如何创建一个简单的REST接口
Jul 30 #Python
Python3爬虫里关于识别微博宫格验证码的知识点详解
Jul 30 #Python
You might like
上海永华YH-R296(华普R-96)12波段立体声收音机的分析和打理
2021/03/02 无线电
PHP的面试题集,附我的答案和分析(一)
2006/11/19 PHP
部署PHP时的4个配置修改说明
2015/10/19 PHP
弹出层之1:JQuery.Boxy (一) 使用介绍
2011/10/06 Javascript
javascript 得到文件后缀名的思路及实现
2020/05/09 Javascript
js闭包所用的场合以及优缺点分析
2015/06/22 Javascript
JS绘制生成花瓣效果的方法
2015/08/05 Javascript
用自定义图片代替原生checkbox实现全选,删除以及提交的方法
2016/10/18 Javascript
微信小程序之MaterialDesign--input组件详解
2017/02/15 Javascript
jQuery序列化后的表单值转换成Json
2017/06/16 jQuery
简单了解JavaScript弹窗实现代码
2020/05/07 Javascript
[57:09]DOTA2-DPC中国联赛 正赛 Phoenix vs Dynasty BO3 第一场 1月26日
2021/03/11 DOTA
Python中的startswith和endswith函数使用实例
2014/08/25 Python
Python中实现的RC4算法
2015/02/14 Python
Python2.x与Python3.x的区别
2016/01/14 Python
Python实现按特定格式对文件进行读写的方法示例
2017/11/30 Python
浅谈python中对于json写入txt文件的编码问题
2018/06/07 Python
用python实现k近邻算法的示例代码
2018/09/06 Python
Python 如何操作 SQLite 数据库
2020/08/17 Python
python爬虫使用scrapy注意事项
2020/11/23 Python
使用HTML5捕捉音频与视频信息概述及实例
2018/08/22 HTML / CSS
使用javascript和HTML5 Canvas画的四渐变色播放按钮效果
2014/04/10 HTML / CSS
会计工作心得体会
2014/01/13 职场文书
自立自强的名人事例
2014/02/10 职场文书
学生安全责任书
2014/04/15 职场文书
转让协议书范本
2014/04/15 职场文书
小学领导班子对照材料
2014/08/23 职场文书
2014年培训工作总结范文
2014/11/27 职场文书
工作试用期自我评价
2015/03/10 职场文书
2015年行政人事工作总结
2015/05/21 职场文书
商业计划书格式、范文
2019/03/21 职场文书
七年级作文之《我和我的祖国》观后感作文
2019/10/18 职场文书
《雪域豹影》读后感:父爱的伟大
2019/12/23 职场文书
Python中的程序流程控制语句
2022/02/24 Python
MySQL七大JOIN的具体使用
2022/02/28 MySQL
Python实战实现爬取天气数据并完成可视化分析详解
2022/06/16 Python