如果每个内置的say_xxx都需要在类里面声明一次,那将是多么可怕的苦役! 不如使用元类来解决问题 。
以下是创建一个专门“打招呼”用的元类代码:
Python
2
3
4
5
class SayMetaClass(type):
def __new__(cls, name, bases, attrs):
attrs['say_'+name] = lambda self,value,saying=name: print(saying+','+value+'!')
return type.__new__(cls, name, bases, attrs)
记住两点:
1、元类是由“type”衍生而出,所以父类需要传入type 。【道生一,所以一必须包含道】
2、元类的操作都在 __new__中完成,它的第一个参数是将创建的类,之后的参数即是三大永恒命题:我是谁,我从哪里来,我将到哪里去 。它返回的对象也是三大永恒命题,接下来,这三个参数将一直陪伴我们 。
在__new__中,我只进行了一个操作,就是
Python
attrs['say_'+name] = lambda self,value,saying=name: print(saying+','+value+'!')
它跟据类的名字,创建了一个类方法 。比如我们由元类创建的类叫“Hello”,那创建时就自动有了一个叫“say_Hello”的类方法,然后又将类的名字“Hello”作为默认参数saying,传到了方法里面 。然后把hello方法调用时的传参作为value传进去,最终打印出来 。
那么,一个元类是怎么从创建到调用的呢?
来!一起根据道生一、一生二、二生三、三生万物的准则,走进元类的生命周期吧
Python
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 道生一:传入type
class SayMetaClass(type):
# 传入三大永恒命题:类名称、父类、属性
def __new__(cls, name, bases, attrs):
# 创造“天赋”
attrs['say_'+name] = lambda self,value,saying=name: print(saying+','+value+'!')
# 传承三大永恒命题:类名称、父类、属性
return type.__new__(cls, name, bases, attrs)
# 一生二:创建类
class Hello(object, metaclass=SayMetaClass):
pass
# 二生三:创建实列
hello = Hello()
# 三生万物:调用实例方法
hello.say_Hello('world!')
输出为
Hello, world!
注意:通过元类创建的类,第一个参数是父类,第二个参数是metaclass
普通人出生都不会说话,但有的人出生就会打招呼说“Hello”,“你好”,“sayolala”,这就是天赋的力量 。它会给我们面向对象的编程省下无数的麻烦 。
现在,保持元类不变,我们还可以继续创建Sayolala,Nihao类,如下:
Python
2
3
4
5
6
7
8
9
# 一生二:创建类
class Sayolala(object, metaclass=SayMetaClass):
pass
# 二生三:创建实列
s = Sayolala()
# 三生万物:调用实例方法
s.say_Sayolala('japan!')
输出
Python
Sayolala, japan!
也可以说中文
Python
2
3
4
5
6
7
8
9
# 一生二:创建类
class Nihao(object, metaclass=SayMetaClass):
pass
# 二生三:创建实列
n = Nihao()
# 三生万物:调用实例方法
n.say_Nihao('中华!')
输出
Python
Nihao, 中华!
再来一个小例子:
Python
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 道生一
class ListMetaclass(type):
def __new__(cls, name, bases, attrs):
# 天赋:通过add方法将值绑定
attrs['add'] = lambda self, value: self.Append(value)
return type.__new__(cls, name, bases, attrs)
# 一生二
推荐阅读
- 首播破亿,口碑两极,《三体》能否帮B站走出“暗黑森林”?
- 丝袜两条线的在哪一边
- 16岁女生标准身高
- 马桶两个孔怎么堵图解
- 钱塘江大潮形成原因是哪两点 钱塘江大潮形成原因
- 辣椒酱的做法
- 豆瓣酱拌茄子的做法
- kamille hand cream_德国的护手霜 一个是Herbacin Wuta Kamille 俗称小甘菊 另一个就叫Kamill 这两种有啥区别
- 淘宝可以同时在两个手机上登录吗
- 湖光秋月两相和的拼音 湖光秋月两相和