• Python元编程


      简单定义“元编程是一种编写计算机程序的技术,这些程序可以将自己看做数据,因此你可以在运行时对它进行内审、生成和/或修改”,本博参考<<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__'])

  • 相关阅读:
    考研系列一-线性表类(顺序存储)
    因特网协议分层及它们的服务模型
    矩阵归零
    字符编码(续)---Unicode与ANSI字符串转换以及分辨字符编码形式
    奇妙的位运算
    一道面试题Lintcode196-Find the Missing Number
    错误处理
    px 和 em 的区别
    简述同步和异步的区别
    简述一下 src 与 href 的区别
  • 原文地址:https://www.cnblogs.com/xiaobingqianrui/p/8435075.html
Copyright © 2020-2023  润新知