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

问题

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

解决方案

在定义类的时候,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定义元类的资料请关注我们其它相关文章!

(0)

相关推荐

  • 举例讲解Python中metaclass元类的创建与使用

    元类是可以让你定义某些类是如何被创建的.从根本上说,赋予你如何创建类的控制权. 元类也是一个类,是一个type类.   元类一般用于创建类.在执行类定义时,解释器必须要知道这个类的正确的元类,如果此属性没有定义,它会向上查找父类中的__metaclass__属性.如果还没发现,就查找全局变量.   对于传统类来说,它们的元类是types.ClassType.   元类也有构造器,传递三个参数:类名,从基类继承数据的元组,和类属性字典. 下面我们来定义一个元类,要求写类的时候必须给类提供一个__s

  • 深入理解Python中的元类(metaclass)

    译注:这是一篇在Stack overflow上很热的帖子.提问者自称已经掌握了有关Python OOP编程中的各种概念,但始终觉得元类(metaclass)难以理解.他知道这肯定和自省有关,但仍然觉得不太明白,希望大家可以给出一些实际的例子和代码片段以帮助理解,以及在什么情况下需要进行元编程.于是e-satis同学给出了神一般的回复,该回复获得了985点的赞同点数,更有人评论说这段回复应该加入到Python的官方文档中去.而e-satis同学本人在Stack Overflow中的声望积分也高达6

  • 深入了解python中元类的相关知识

    类也是对象 在大多数编程语言中,类就是一组用来描述如何生成一个对象的代码段,在python中也是成立的. class ObjectCreator: pass my_object = ObjectCreator() print(my_object) """ 输出结果: <__main__.ObjectCreator object at 0x037DACD0> """ 但是,python的类不止于此,类同样也是一种对象. class Ob

  • Python中的元类编程入门指引

    回顾面向对象编程 让我们先用 30 秒钟来回顾一下 OOP 到底是什么.在面向对象编程语言中,可以定义 类,它们的用途是将相关的数据和行为捆绑在一起.这些类可以继承其 父类的部分或全部性质,但也可以定义自己的属性(数据)或方法(行为).在定义类的过程结束时,类通常充当用来创建 实例(有时也简单地称为 对象)的模板.同一个类的不同实例通常有不同的数据,但"外表"都是一样 - 例如, Employee 对象 bob 和 jane 都有 .salary 和 .room_number ,但两者

  • 在Python中使用元类的教程

    type() 动态语言和静态语言最大的不同,就是函数和类的定义,不是编译时定义的,而是运行时动态创建的. 比方说我们要定义一个Hello的class,就写一个hello.py模块: class Hello(object): def hello(self, name='world'): print('Hello, %s.' % name) 当Python解释器载入hello模块时,就会依次执行该模块的所有语句,执行结果就是动态创建出一个Hello的class对象,测试如下: >>> fro

  • Python 使用元类type创建类对象常见应用详解

    本文实例讲述了Python 使用元类type创建类对象.分享给大家供大家参考,具体如下: type("123") 可以查看变量的类型;同时 type("类名",(父类),{类属性:值,类属性2:值}) 可以创建一个类. 在Python中不建议一个函数具有不同的功能(重载):type()具有不同的功能是为了兼容之前的版本. 类可以创建实例对象,类对象是由元类创建的. (元类创建类,类创建实例对象) type就是元类(type本质上就是一个类) demo.py(用元类t

  • Python 元类使用说明

    我要一大群的类都具有一中特点,我怎么给他们加上呢?模板模板吗,我从这个模板创建一群类不就OK了?那就需要元类了.霍霍> 定义一个元类(就所一个类的模板!莫多想,还要记住这是类级别的,不是对象级别的!): 复制代码 代码如下: class MyMeta(type): def __init__(cls,name,bases,dic): print cls.__name__ print name def __str__(cls):return 'Beautiful class %s'%cls.__na

  • Python 元类实例解析

    龟叔发明了 Python,然后集成了一堆概念在这门语言里面,比如:迭代器,装饰器,函数,生成器,类,对象,协程等等. 这些概念对初学者似乎没一个好懂的,不过还有比这更难的概念,它是 Python 世界中的造物主,虽然我们很少去直接使用它,但天天都在用,它就是今天的主角------元类. 今天我的任务就是彻底明白什么是元类,一起看看. 要搞懂元类,我们还是先从对象说起. 对象(Object) Python 一切皆对象,这句话你一定有听说过(现在你就听说了),一个数字是对象,一个字符串是对象,一个列

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

    问题 你想定义一个元类,允许类定义时提供可选参数,这样可以控制或配置类型的创建过程. 解决方案 在定义类的时候,Python允许我们使用 ``metaclass``关键字参数来指定特定的元类. 例如使用抽象基类: from abc import ABCMeta, abstractmethod class IStream(metaclass=ABCMeta): @abstractmethod def read(self, maxsize=None): pass @abstractmethod de

  • Python如何定义有默认参数的函数

    问题 你想定义一个函数或者方法,它的一个或多个参数是可选的并且有一个默认值. 解决方案 定义一个有可选参数的函数是非常简单的,直接在函数定义中给参数指定一个默认值,并放到参数列表最后就行了.例如: def spam(a, b=42): print(a, b) spam(1) # Ok. a=1, b=42 spam(1, 2) # Ok. a=1, b=2 如果默认参数是一个可修改的容器比如一个列表.集合或者字典,可以使用None作为默认值,就像下面这样: # Using a list as a

  • 详解如何创建Python元类

    什么是Python元类? Python元类是与Python的面向对象编程概念相关的高级功能之一.它确定类的行为,并进一步帮助其修改. 用Python创建的每个类都有一个基础的Metaclass.因此,在创建类时,您将间接使用元类.它隐式发生,您无需指定任何内容. 与元编程相关联的元类决定了程序对其自身进行操作的能力. 学习元类可能看起来很复杂,但是让我们先从一些类和对象的概念入手,以便于理解. Python中的类和对象 类是一个蓝图,是具有对象的逻辑实体. 一个简单的类在声明时没有分配任何内存,

  • python利用元类和描述器实现ORM模型的详细步骤

    ORM模型: ORM模型对于后端开发来说肯定是不陌生的,包括很多后端框架比如django,现在都自带这个模型了 ORM(Object Relational Mapping)对象关系映射 Python中的类与数据库之间的映射,对数据的操作就不用编写SQL语言了,因为都封装好了,比如你想插入一条数据,你就直接创建一个对象即可, 类名 ------->>>> 数据库中的表名 属性 ------->>>> 数据库中的字段 对象 ------->>>

  • Python超详细讲解元类的使用

    目录 类的定义 一.什么是元类 二.注意区分元类和继承的基类 三.type 元类的使用 四.自定义元类的使用 类的定义 对象是通过类创建的,如下面的代码: # object 为顶层基类 class Work(object): a = 100 Mywork = Work() # 实例化 print(Mywork ) # Mywork 是 Work 所创建的一个对象 <__main__.Work object at 0x101eb4630> print(type(Mywork)) # <cl

  • Python中函数的参数定义和可变参数用法实例分析

    本文实例讲述了Python中函数的参数定义和可变参数用法.分享给大家供大家参考.具体如下: 刚学用Python的时候,特别是看一些库的源码时,经常会看到func(*args, **kwargs)这样的函数定义,这个*和**让人有点费解.其实只要把函数参数定义搞清楚了,就不难理解了. 先说说函数定义,我们都知道,下面的代码定义了一个函数funcA def funcA(): pass 显然,函数funcA没有参数(同时啥也不干:D). 下面这个函数funcB就有两个参数了, def funcB(a,

  • Python中函数及默认参数的定义与调用操作实例分析

    本文实例讲述了Python中函数及默认参数的定义与调用操作.分享给大家供大家参考,具体如下: #coding=utf8 ''''' Python中的函数使用小括号调用.函数在调用之前必须先定义. 如果函数中没有return语句,就会自动返回None对象. Python是通过引用调用的.如果函数内对参数的改变会影响到原始对象. 只有可变对象会受此影响,对不可变对象,它的行为类似按值调用. ''' ''''' 定义函数: def function_name([arguments]): "option

  • python中fastapi设置查询参数可选或必选

    目录 可选查询参数 必选查询参数 可选和必选参数共存 为可选参数做类型提示 前言: 在fastapi中,我们定义的查询参数是可以设置成:必选参数 or 可选参数. 可选查询参数 z只要给查询参数的默认值设置为None,表示该查询参数是可选参数.  from fastapi import FastAPI  ​  app = FastAPI()​  @app.get("/items/{item_id}")  async def read_item(item_id: str, q=None)

  • Python定义函数时参数有默认值问题解决

    这篇文章主要介绍了Python定义函数时参数有默认值问题解决,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 在定义函数的时候,如果函数的参数有默认值,有两种类型的参数,一种是整数,字符串这种不可变类型,另一种是列表这种可变类型,对于第一种情况没有什么特殊的地方,但是对于可变类型,有一个微妙的小陷阱. 可变类型以及小陷阱: def append_item(item, list1=[]): list1.append(item) return lis

  • python中元类用法实例

    本文实例讲述了python中元类用法,分享给大家供大家参考.具体方法分析如下: 1.元类(metaclass)是用来创建类的类 2.type(object):返回一个对象的类型,与object.__class__的值相同,type(name,bases,dict):创建一个新的type类型,name就是新class的name,值存到__name__属性中,bases是tuple类型,值会存到__bases__中,dict的值存到__dict__中 复制代码 代码如下: class X: ... 

随机推荐