Python深入浅出分析元类

目录
  • 一、类和对象
  • 二、type类
  • 三、元类Metaclass
  • 四、自定义一个元类

一、类和对象

Python属于动态类型的语言,而动态语言和静态语言最大的不同,就是函数和类的定义,不是编译时创建的,而是运行时动态创建的,比方说我们要定义一个 Person 的class,就写一个 Person.py 模块:

# -*- coding: utf-8 -*-
# 文件名  : Person.py
class Person(object):
    def say(self, s='元类'):
        print('今日学习:%s' % s)
if __name__ == '__main__':
    p = Person()
    p.say()

当Python解释器载入 Person 模块时,就会依次执行该模块的所有语句,执行结果就是动态创建出一个 Person 的class对象,测试如下,(注意,是引入一个Person.py脚本)

# 文件名 :测试.py
# 引入模块,需要模块的路径
from Person import Person
# 创建一个Person类的实例
p = Person()
p.say('Python中的元类')  # 调用say方法
# 今日学习:Python中的元类
print(type(p))  # 把实例 p 的类型打印出来
# <class 'say.Person'>
print(type(Person))  # Person 类的类型打印出来
# <class 'type'>

这里是用来 type() 函数,可以查看一个类型或变量,的类型, Person 是一个class,它的类型就是 type ,而 p是一个实例,它的类型就是class Person

二、type类

我们说class的定义是运行时动态创建的,而创建class的方法就是使用 type() 函数

type() 函数既可以返回一个对象的类型,又可以创建出新的类型,比如,我们可以通过 type() 函数创建出Person 类,而无需通过 class Person(object)... 的定义,此时type的第二种用法,我们只要type传object是可以返回该对象类型的,但是当我们的type存在三位参数存在时

# type 类
class type(object):
    """
    type(object_or_name, bases, dict)
    type(object) -> the object's type
    type(name, bases, dict) -> a new type
    """
#参数介绍
"""
type(object_or_name, bases, dict)
object-or-name -- 对象或类的名称。
bases -- 基类的元组。
dict -- 字典,类内定义的命名空间变量。
"""
# 返回新的类型对象。
# -*- coding: utf-8 -*-
def fun(self, s):
    print('hello'+s)
Hello = type('hello', (object,), dict(func=fun))
if __name__ == '__main__':
    h = Hello()
    h.func(' word')
    # hello word
    print(type(h))
    # <class '__main__.hello'>
    print(type(Hello))
    # <class 'type'>  

我们通过 type() 函数创建的类和直接写class是完全一样的,因为Python解释器遇到class定义时,仅仅是扫描一下class定义的语法,然后调用 type() 函数创建出class

在正常情况下,我们都用 class Xxx... 来定义类,但是, type() 函数也允许我们动态创建出类来,也就是说,动态语言本身支持运行期动态创建类,这和静态语言有非常大的不同,要在静态语言运行期创建类,必须构造源代码字符串再调用编译器,或者借助一些工具生成字节码实现,本质上都是动态编译,会非常复杂

三、元类Metaclass

除了使用 type() 动态创建类以外,要控制类的创建行为,还可以使用metaclass,也就是元类

当我们定义了类以后,就可以根据这个类创建出实例,所以:先定义类,然后创建实例

但是如果我们想创建出类呢?那就必须根据metaclass创建出类,所以:先定义metaclass,然后创建类,元类就是用来创建这些类(对象)的,元类就是类的类

我们先看一个简单的例子,这个metaclass可以给自定义的类增加一个 add 方法定义 ListMetaclass ,按照默认习惯,metaclass的类名总是以Metaclass结尾,以便清楚地表示这是一个metaclas。

四、自定义一个元类

class UpperMetaclass(type):
    def __new__(mcs, class_name, class_parents, class_attrs):
        new_attrs = {}
        for name, value in class_attrs.items():
            if not name.startswith('__'):  # 判断是否为非私有属性
                new_attrs[name.upper()] = value
        # 直接调用type 来创建一个类
        return type.__new__(mcs, class_name, class_parents, class_attrs)
# 测试
class Emp(object, metaclass=UpperMetaclass):
    name = '张三'
    acl = 500
if __name__ == '__main__':
    print(hasattr(Emp, 'name'))  # 判断Emp中是否有名字为name
    print(hasattr(Emp, 'NAME'))  # 判断Emp中是否有名字为NAME

到此这篇关于Python深入浅出分析元类的文章就介绍到这了,更多相关Python元类内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Python基础之元类详解

    1.python 中一切皆是对象,类本身也是一个对象,当使用关键字 class 的时候,python 解释器在加载 class 的时候会创建一个对象(这里的对象指的是类而非类的实例) class Student: pass s = Student() print(type(s)) # <class '__main__.Student'> print(type(Student)) # <class 'type'> 2.什么是元类 元类是类的类,是类的模板 元类是用来控制如何创建类的,

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

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

  • Python自定义元类的实例讲解

    1.说明 一个类没有声明自己的元类,默认他的元类就是type,除了使用元类type,用户也可以通过继承type来自定义元类. 2.实例 我们可以使用类属性 __metaclass__ 把一个类的创建过程,转交给其它地方. class A(object): __metaclass__ = ... # 这个类的创建转交给其他地方 pass 先定义了类 A,然后定义了一个类属性 __metaclass__,这个属性表示创建类 A 的过程,转交给其它地方处理. 类属性 __metaclass__ 可以是

  • python中的type,元类,类,对象用法

    目录 type,元类,类,对象 简单描述 类的生成方式 元类 元类type学习总结 type的作用是干什么呢? type,元类,类,对象 简单描述 1.type是python内建元类,新建的元类需要继承type 2.元类用来创建类,类用来创建对象 类的生成方式 传统定义通过声明关键字class #1.创建Person类 #2.继承object #3.拥有属性eat class Person(object):     def eat(self,food="rice"):        

  • 深入理解Python的元类

    目录 什么是元类 type元类动态创建类 自定义元类 总结 什么是元类 Python中,一切皆对象,我们定义的数字.字符串.函数.列表等都是对象,对象是类(class)的是实例,而类(class)其实也是对象,是type的实例.这个type就是Python中的元类(metaclass).所谓元类就是用于创建所有类型的类,Python中的所有新式类以及Python3中的所有类都是type元类的实例.我们看下面这个例子: print(type(0)) # <class 'int'> print(t

  • 详解如何创建Python元类

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

  • python 使用元类type创建类

    目录 1.type动态创建类 1.1 语法格式 1.2 案例1:使用type创建类 1.3 案例2:使用type创建带有属性(方法)的类 1.4 案例3:使用type动态创建一个继承指定类的类 前言: 通常我们创建类都是使用class 类名,但是小伙伴们有没有想过,类是由谁来创建的呢,python中常说的万物皆对象,对象是由类创建的,那类本身也可以看做是对象,类可以由元类type创建 1.type动态创建类 1.1 语法格式 type(类名,由父类名称组成的元组(可以为空),包含属性的字典(名称

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

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

  • Python元类与迭代器生成器案例详解

    1.__getattr__和__getattribute__魔法函数 __getattr__是当类调用一个不存在的属性时才会调用getattr魔法函数,他传入的值item就是你这个调用的不存在的值. __getattribute__则是无条件的优先执行,所以如果不是特殊情况最好不要用__getattribute__. class User(object): def __init__(self, name, info): self.name = name self.info = info def

  • Python深入浅出分析元类

    目录 一.类和对象 二.type类 三.元类Metaclass 四.自定义一个元类 一.类和对象 Python属于动态类型的语言,而动态语言和静态语言最大的不同,就是函数和类的定义,不是编译时创建的,而是运行时动态创建的,比方说我们要定义一个 Person 的class,就写一个 Person.py 模块: # -*- coding: utf-8 -*- # 文件名 : Person.py class Person(object): def say(self, s='元类'): print('今

  • Python深入浅出分析enum枚举类

    目录 枚举类Enum 总结 枚举类Enum 枚举类,在企业开发中用的比较多 当我们需要定义常量时,一个办法是用大写的变量通过整数来定义,例如月份: # 当项目中需要使用12个月份时JAN = 1FEB = 2...NOV = 11DEC = 12 但是这样的定义的类型是 int ,并且仍然是变量,并且在运算中,无法时时创建对应的值,当然这种指代是以更好的方式去使用变量数值. 这里存在更好的方法是为这样的枚举类型定义一个class类型,然后,每个常量都是class的一个唯一实例.Python提供了

  • 详解python metaclass(元类)

    元编程,一个听起来特别酷的词,强大的Lisp在这方面是好手,对于Python,尽管没有完善的元编程范式,一些天才的开发者还是创作了很多元编程的魔法.Django的ORM就是元编程的一个很好的例子. 本篇的概念和例子皆在Python3.6环境下 一切都是对象 Python里一切都是对象(object),基本数据类型,如数字,字串,函数都是对象.对象可以由类(class)进行创建.既然一切都是对象,那么类是对象吗? 是的,类也是对象,那么又是谁创造了类呢?答案也很简单,也是类,一个能创作类的类,就像

  • 深入浅出分析Java 类和对象

    目录 一.什么是类 二.Java的类和C语言的结构体异同 三.类和类的实例化 类的声明 实例化的对象,成员遵循默认值规则 类的实例化 静态属性(静态成员变量) 四.构造方法 创建构造方法 this 一.什么是类 类(Class)是面向对象程序设计(OOP,Object-Oriented Programming)实现信息封装的基础.类是一种用户自定义的引用数据类型,也称类类型.每个类包含数据说明和一组操作数据或传递消息的函数,类的实例称为对象 类的实质是一种引用数据类型,类似于 byte,shor

  •  python中的元类metaclass详情

    目录 动机 从一个问题引出 MetaClass Metaclass 编程 动机 python语言因为工作偏向于 AI ,所以对于这门语言还停留在表面,对于 python 深层并没有接触到. 今天来聊一聊元类(metaclass) ,想必大多数人都或多或少听过元编程这个词,但是对于元编程是什么以及如何应用元编程熟悉应该不多,在 python 中的 metaclass 就是帮助 developer 实现元编程,因此产生一个想法 最近时间还算宽裕,所以想要文章认真弄一弄 从一个问题引出 MetaCla

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

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

  • 在Python中使用元类的教程

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

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

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

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

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

随机推荐