Python元编程

1.概述Python元编程有两种方法,一是采用类似“装饰器”的工具对基本元素(例如函数、类、类型)内审和对其进行实时创建和修改,二是运用类型"元类"的方式对类实例的创建过程进行

大家好,又见面了,我是全栈君,今天给大家准备了Idea注册码。

全栈程序员社区此处内容已经被作者隐藏,请输入验证码查看内容
验证码:
请关注本站微信公众号,回复“验证码”,获取验证码。在微信里搜索“全栈程序员社区”或者“www_javaforall_cn”或者微信扫描右侧二维码都可以关注本站微信公众号。

  简单定义“元编程是一种编写计算机程序的技术,这些程序可以将自己看做数据,因此你可以在运行时对它进行内审、生成和/或修改”,本博参考<<Python高级编程>>将对元编程内容进行详细描述,若有不正确之处希望大家指出。

1. 概述

  Python元编程有两种方法,一是采用类似“装饰器”的工具对基本元素(例如函数、类、类型)内审和对其进行实时创建和修改,二是运用类型”元类”的方式对类实例的创建过程进行修改,甚至于允许重新设计Python面对对象编程范式的实现。

2. 装饰器

  关于装饰器的内容可以阅读上篇博客<<Python装饰器>>,链接:http://www.cnblogs.com/xiaobingqianrui/p/8435074.html

  对wraps装饰器的使用进行补充说明,在类装饰器中使用闭包会导致生成的对象不再是被装饰的类的实例,二是在装饰器函数创建的子类的实例,这会影响__name__和__doc__等属性,在上篇我们使用@wraps装饰器对函数装饰器进行操作让问题得到解决,但在类装饰器中这一方法无效。

3. 元类

  元类是Python的一个重要特性,是定义其他类的类,理解其工作方式,最重要的是要知道定义了对象实例的类也是对象,那么它一定有与其相关联的类,所有的类定义的基类都是内置的type类。

#coding=utf-8

class MyClass:
    pass

if __name__ == "__main__":
    myclass = MyClass()
    print ("type of myclass:", type(myclass))
    print ("type of MyClass:", type(MyClass))

>>> type of myclass: <class ‘__main__.MyClass’>
>>> type of MyClass: <class ‘type’>

3.1 type()语法

  type()类作为class语句的动态等效,给定类名,基类名和属性映射会创建一个新类 

#coding=utf-8

def func1(self):
    print (1)

def func2(*argv):
    print (argv)

if __name__ == "__main__":
    MyClass = type("MyClass",(object, ), {"func1":func1, "func2":func2})
    a = MyClass()
    print (type(a))
    a.func1()
    a.func2(2)

>>> <class ‘__main__.MyClass’>
>>> 1
>>> (<__main__.MyClass object at 0x01A02270>,2)

3.2 元类的常用模板 

#coding=utf-8

'''元类模板 '''
class MyClass(type):
#创建一个空的命名空间,返回一个空的dict   
    @classmethod
    def __prepare__(mcs, name, bases, **kwargs):
        print ("MyClass __prepare__")
        return super().__prepare__(name, bases, **kwargs)   

    def __new__(mcs, name, bases, namespace):
        print ("MyClass __new__")
        return super().__new__(mcs, name, bases, namespace)

    def __init__(cls, name, bases, namespace, **kdargv):
        print ("MyClass __init__")   
        super().__init__(name, bases, namespace)

    def __call__(cls, *argv, **kdargv):
        print ("MyClass __call__")
        return super().__call__(*argv, **kdargv)

class _MyClass(metaclass=MyClass):
    def __new__(cls):
        print ("_MyClass __new__")
        return super().__new__(cls)

    def __init__(self):
        print("__MyClass __init__")
        super().__init__()

if __name__ == "__main__":
    a =  _MyClass()
    

>>> MyClass __prepare__
>>> MyClass __new__
>>> MyClass __init__
>>> MyClass __call__
>>> _MyClass __new__
>>> __MyClass __init_

用class语句创建的每个类都隐式的使用type作为元类,可以用metaclass=“指定元类”的方式改变这一默认行为。

3.3 元类的使用

  元类是一种非常强大的特性,但总是会是代码更加复杂,将其用于任意类型的类时,这可能会降低代码的鲁棒性,我们必须灵活的使用元类。

#coding=utf-8

class OrderedMeta(type):
    @classmethod
    def __prepare__(mcs, name, bases, **kdargv):
        return super().__prepare__(mcs, name, bases, **kdargv)

    def __new__(mcs, name, bases, namespace):
        namespace["orderofattr"] = list(namespace.keys())
        return super().__new__(mcs, name, bases, namespace)
        
class test(metaclass = OrderedMeta):
    first = 8
    secord = 2

if __name__ == "__main__":
    print (test.orderofattr)    
    print (test.__dict__.keys())

>>> [‘__module__’, ‘__qualname__’, ‘first’, ‘secord’]
>>> dict_keys([‘__module__’, ‘first’, ‘secord’, ‘orderofattr’, ‘__dict__’, ‘__weakre
>>> f__’, ‘__doc__’])

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/120208.html原文链接:https://javaforall.net

(0)
上一篇 2021年12月18日 下午4:00
下一篇 2021年12月18日 下午5:00


相关推荐

  • 卡尔曼滤波 原理(卡尔曼滤波5个重要公式讲解)

    详解卡尔曼滤波原理  在网上看了不少与卡尔曼滤波相关的博客、论文,要么是只谈理论、缺乏感性,或者有感性认识,缺乏理论推导。能兼顾二者的少之又少,直到我看到了国外的一篇博文,真的惊艳到我了,不得不佩服作者这种细致入微的精神,翻译过来跟大家分享一下,

    2022年4月14日
    475
  • linux下查看tomcat宕机并自动重启[通俗易懂]

    linux下查看tomcat宕机并自动重启[通俗易懂]1.在服务器上创建tomcatMonitor.sh2.使文件生效chmodu+x*.sh3.编辑tomcatMonitor.sh文件,if及fi必须成对出现,如果ifthen写在一行需要用;隔开#!/bin/sh#获取tomcat的PIDTOMCAT_PID=$(ps-ef|greptomcat|grep-v’grep’|awk'{print$2}’)#tomcat的启动文件位置START_TOMCAT=/usr/local/tomcat6/bin/start

    2022年7月23日
    11
  • 【SpringBoot优点】

    【SpringBoot优点】SpringBoot 优点

    2026年3月16日
    2
  • VMM分类_nmm组合

    VMM分类_nmm组合VMM可以分为:完全虚拟化(基于硬件)、宿主虚拟化、混合虚拟化 (1).完全虚拟化VMM虚拟的是现实存在的平台,在客户及操作系统看来,虚拟的平台和现实的平台是一样的,客户机操作系统察觉不到市运行在一个虚拟平台上X86架构的完全虚拟化,经历了两个阶段:软件辅助的完全虚拟化Ringcompression   VMM运行在Ring0,客户及操作系统运行在V

    2026年2月18日
    7
  • 【已解决】Redis连接——Could not connect to Redis at 127.0.0.1:6379: Connection refused[通俗易懂]

    【已解决】Redis连接——Could not connect to Redis at 127.0.0.1:6379: Connection refused[通俗易懂]相信很多人很可能刚上手使用Redis时,很容易遇到的问题就是CouldnotconnecttoRedisat127.0.0.1:6379:Connectionrefused。由于只是记录bug解决,所以开门见山,宜春不多哔哔…其实原因很简单,这个问题一般是关闭了服务端导致客户端打不开,最简单快捷解决办法就是先开启服务端,再去连接客户端!如下:开启服务端需要先配置(redis.con…

    2022年6月6日
    1.1K
  • FPGA–modelsim仿真工具的破解

    FPGA–modelsim仿真工具的破解1、先把modelsim安装到电脑上;2、将解压的破解文件(MentorKG.exe和patch_dll.bat)复制到modelsim安装目录下的win64文件夹中;3、进入安装目录下的win64文件夹找到mgls.dll、mgls64.dll两个文件,去掉只读属性;4、运行patch_dll.bat(双击该文件即可,有的教程是通过cmd运行的,不过没有直接双击方便快捷),稍等一段时…

    2022年5月23日
    49

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号