元编程


    physics,即物理学,是研究物质、能量的本质与性质,以及它们彼此之间相互作用的自然科学。
    metaphysics, 被翻译为「形而上学」,由日本人 井上哲次郎 于 明治时代 翻译为汉字词语,指研究事物本身的学问。通常人们在谈论形而上学时,往往将它作为一种哲学上的讨论--关于根本(或者存在)本身的意义。

    meta前缀,源于希腊语,其本意是「在…后,越过…的」,而后在西方哲学界的发展中渐渐赋予该词缀一种全新的意义:关于某事自身的某事。比如 meta-knowledge 就是「关于知识本身的知识」,meta-data 就是「关于数据的数据」,meta-language 就是「关于语言的语言」,而 meta-programming 也是由此而来,是「关于编程的编程」。

meta在中国大陆多被翻译为「元」,在台湾多被翻译为「后设」

什么是元编程

元编程的目的是操作其他的程序(或自身)作为它自身的数据,在运行时完成它本应该在编译时应该完成的任务。

一个使用bash脚本描述的元程序


#!/bin/bash
# metaprogram
echo '#!/bin/bash' >program
for ((I=1; I<=992; I++)) do
    echo "echo $I" >>program
done
chmod +x program

元编程的能力在很大的程度上也和选择的语言有关系,比如:C/C++ 的宏, Java的反射和动态代理……
而像Python这种动态性强的语言,给对象加个属性、方法啥的,简直不值一提。

一切都是对象……吗?

继在(类)Unix世界喊出了「一切皆是文件」的口号之后,Python世界也喊出了「一切皆是对象」的口号。

不信?打开终端,随便输入点什么,来看看结果


>>> type("a")
<class 'str'>
>>> type(1)
<class 'int'>
>>> type([])
<class 'list'>
>>> type({})
<class 'dict'>
>>> type(Exception())
<class 'Exception'>
>>> type(object())
<class 'object'>

如果你有一个自定义的类<e>Person</e>, 就会有


>>> EvinK = Person()
>>> type(EvinK)
<class 'Person'>

上面所有的东西,都被type()识别为某个class(对象)的实例。

对象的对象

Python世界里所有的对象都继承于object对象,使用isinstance(instance, object)就可以验证这一点。但是,object又是什么类型呢?按照直觉的话,它应该还是一个object类型,多说无益,开一个终端来测试一下吧!


>>> type(object)
<class 'type'>
>>> type(type)
<class 'type'>
>>> isinstance(object, object)
True
>>> isinstance(object, type)
True
>>> isinstance(type, object)
True
>>> isinstance(type, type)
True

原来,object 是一个 type 类型。

type 不光作为一个类型鉴定函数,居然是一个类。那既然是类,肯定也 object 的子类,但是同时, objecttype 的一个实例,于是间接地 object 也成为了自身的实例(由于 typeobject 的继承关系)。

python-type-instance.png

由此推论,所有继承于 object 的类(即Python中的所有对象),都是 type 的一个实例。

type 在此就作为这些类的类之存在,并用来定义这些类中的属性的方法。它是Python世界里最为特殊的一个对象,一个用来操纵对象的对象。它是 object 的子类, object 是它的实现。

使用type来定义一个类

一个已知的定义类的方式(如下),已经写入了各种文章中


class Person:
    """
    Person Document
    """
    # 类变量
    name = "EvinK"
    # 私有类变量
    __private_var = 1

    # 实际上的构造函数
    def __new__(cls, *args, **kwargs):
        cls.age = kwargs["age"]
        return cls

    # 此方法将不会被执行
    def __init__(self, age):
        self.age_ = age

    # 静态方法
    @staticmethod
    def get_private_var():
        return Person.__private_var

    # 类方法
    @classmethod
    def get_last_age(cls):
        # 返回最后一个实例的age
        return cls.age

if __name__ == "__main__":

    print(Person.__dict__)

    {
        '__module__': '__main__',
        '__doc__': '\n    Person Document\n    ',
        'name': 'EvinK',
        '_Person__private_var': 1,
        '__new__': <staticmethod object at 0x7f98aec409b0>,
        '__init__': <function Person.__init__ at 0x7f98acf25840>,
        'get_private_var': <staticmethod object at 0x7f98aec40908>,
        'class_method': <classmethod object at 0x7f98aec40ac8>,
        '__dict__': <attribute '__dict__' of 'Person' objects>,
        '__weakref__': <attribute '__weakref__' of 'Person' objects>
    }

    evink = Person(age=13)
    print(evink.__dict__)

    {
        '__module__': '__main__',
        '__doc__': '\n    Person Document\n    ',
        'name': 'EvinK',
        '_Person__private_var': 1,
        '__new__': <staticmethod object at 0x7f4e297d8d30>,
        '__init__': <function Person.__init__ at 0x7f4e297db840>,
        'get_private_var': <staticmethod object at 0x7f4e2b4f6ac8>,
        'class_method': <classmethod object at 0x7f4e2b4f69b0>,
        '__dict__': <attribute '__dict__' of 'Person' objects>,
        '__weakref__': <attribute '__weakref__' of 'Person' objects>,
        'age': 13
    }

上述的类被一个字典给描述,其中包含有这个类的类变量 , 静态方法类方法 , 方法构造方法 。而类的实例也可以被一个字典描述,只不过多了写 实例变量 而已。这两者的结构看上去是如此的相似,但是一个是类型(type的实例),一个是(类的)实例。

既然通过类的构造方法就可以生成实例,那作为 type 实例的类,是不是也可以由 type 生成呢?


Person = type("Person", (), dict(
        name="EvinK",
        # 使用type生成的类声明将不会被转换为 _Person__private_var 这种形式
        __private_var=1
    ))

Person.__doc__ = \
        """
            Person
        """

@staticmethod
def new(cls, *args, **kwargs):
        return cls

# 出现__new__方法时, 此构造将不会被执行
def init(self, age):
        self.age = age

Person.__init__ = init
Person.__new__ = new

上面由type生成的类,使用 __dict__ 属性时,可以看到,基本和我们使用 class 关键字声明的类长得一样。这对某些静态类型的语言来说简直是天方夜谭!

未完待续……

原文地址: https://code.evink.me/2018/09/post/Meta-Programming/

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,293评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,604评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,958评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,729评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,719评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,630评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,000评论 3 397
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,665评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,909评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,646评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,726评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,400评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,986评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,959评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,197评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,996评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,481评论 2 342

推荐阅读更多精彩内容

  • 今天转载一片非常精彩的文章供大家欣赏:参考文章链接.python开发者门户一个很好的学习python的网站,大家有...
    KillerManA阅读 776评论 0 3
  • 我妄想有一天流浪世间, 听惯所有草长莺飞, 看遍所有赫赫炎炎 听惯所有秋风过耳 看遍所有...
    东南西北李姐姐阅读 381评论 0 1
  • 变压器和数据线:异常重要,而且最容易被人们忽视。 变压器直接决定充电电压,好的变压器电压稳定,充电速度会非常快。 ...
    履霜阅读 537评论 0 6
  • 隔壁楼下不好吃的生煎。 周四这天,最不好的体会是,FQZ提了四个,只有一个被确认,所以觉得很灰心。也不清楚鼓励我们...
    小王子的前世今生阅读 173评论 0 0
  • “当今时代,最高的艺术形式就是时尚。” Kanye West在一个采访中说到。或许他说的有些道理,有时当世界上的时...
    独立时尚杂志_匠临阅读 769评论 0 1