首页 > 编程 > Python > 正文

Python中的元类编程入门指引

2020-02-23 00:44:40
字体:
来源:转载
供稿:网友

回顾面向对象编程

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

一些 OOP 语言(包括 Python)允许对象是 自省的(也称为 反射)。即,自省对象能够描述自己:实例属于哪个类?类有哪些祖先?对象可以用哪些方法和属性?自省让处理对象的函数或方法根据传递给函数或方法的对象类型来做决定。即使没有自省,函数也常常根据实例数据进行划分,例如,到 jane.room_number 的路线不同于到 bob.room_number 的路线,因为它俩在不同的房间。利用自省, 还可以在安全地计算 jane 所获奖金的同时,跳过对 bob 的计算,例如,因为 jane 有 .profit_share 属性,或者因为 bob 是子类 Hourly(Employee) 的实例。

元类编程(metaprogramming)的回答

以上概述的基本 OOP 系统功能相当强大。但在上述描述中有一个要素没有受到重视:在 Python(以及其它语言)中,类本身就是可以被传递和自省的对象。正如前面所讲到的,既然可以用类作为模板来生成对象,那么用什么 作为模板来生成类呢?答案当然是 元类(metaclass)。

Python 一直都有元类。但元类中所涉及的方法在 Python 2.2 中才得以更好地公开在人们面前。Python V2.2 明确地不再只使用一个特殊的(通常是隐藏的)元类来创建每个类对象。现在程序员可以创建原始元类 type 的子类,甚至可以用各种元类动态地生成类。当然,仅仅因为 可以在 Python 2.2 中操作元类,这并不能说明您可能想这样做的原因。

而且,不需要使用定制元类来操作类的生成。一种不太费脑筋的概念是 类工厂:一种普通的函数,它可以 返回在函数体内动态创建的类。用传统的 Python 语法,您可以编写:
清单 1. 老式的 Python 1.5.2 类工厂

Python 1.5.2 (#0, Jun 27 1999, 11:23:01) [...]Copyright 1991-1995 Stichting Mathematisch Centrum, Amsterdam>>> def class_with_method(func):...   class klass: pass...   setattr(klass, func.__name__, func)...   return klass...>>> def say_foo(self): print 'foo'...>>> Foo = class_with_method(say_foo)>>> foo = Foo()>>> foo.say_foo()foo

工厂函数 class_with_method() 动态地创建一个类,并返回该类,这个类包含传递给该工厂 的方法/函数。在返回该类之前,在函数体内操作类自身。 new 模块提供了更简洁的编码方式,但其中的选项与 类工厂体内定制代码的选项不同,例如:

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表