元类type

1. 创建类的两种方式 (都是由type元类创建)

方式一:

class Foo(object):      # 默认metaclass = type, 当前类, 由type类创建
a = 'aaa'
def func(self, x):
return x + 1

方式二:

Foo = type("Foo", (object, ), {'a': "aaa", 'func': lambda self, x: x + 1})

metaclass

作用:
  通过metaclass可以指定当前类由哪一个元类创建

python2和python3的区别:

    python3:
class Foo(object, metaclass=type):
pass python2:
class Foo(object):
__metaclass__=type
pass

自定义元类

1、第一步

class MyType(type):
def __init__(self, *args, **kwargs):
print("创建类之前")
super(MyType, self).__init__(*args, **kwargs)
print("创建类之后")

2、第二步

class Base(object, metaclass=MyType):
pass

Base = MyType('Base', (object, ), {})

这两部代码写完后,执行:

输出:

  创建类之前
  创建类之后

因为:  代码一执行, 就创建一个类,由MyType创建Foo类,就执行Mytype的__init__方法了

3、第三步

class Foo(Base):         # 基类由MyType创建,Bar也由MyType创建
a = 'aaa' def func(self, x):
return x + 1

现在有3个类, 运行脚本,会打印2遍("创建类之前","创建类之后")

元类__new__/__init__/__call__的执行顺序

class MyType(type):
def __init__(self, *args, **kwargs):
print("MyType: __init__")
super(MyType, self).__init__(*args, **kwargs) def __call__(self, *args, **kwargs):
print('MyType: __call__')
super(MyType, self).__call__(*args, **kwargs) def with_metaclass(arg):
return MyType('Base', (arg,), {}) class Foo(with_metaclass(object)):
a = 'aaa' def __init__(self, *args, **kwargs):
print('Foo: __init__')
super(Foo, self).__init__(*args, **kwargs) def __new__(cls, *args, **kwargs):
print('Foo: __new__')
return super(Foo, cls).__new__(cls) def func(self, x):
return x + 1 b = Foo() # MyType: __init__ 这个是创建Base类的时候执行MyType的__init__
# MyType: __init__ 创建Foo类的时候,执行MyType的__init__
# MyType: __call__ 实例化 Foo(), 先执行MyType的__call__, 再执行Foo的__new__和__init__
# Foo: __new__ 然后才会执行Foo的__new__方法
# Foo: __init__     最后执行Foo的__init__方法

总结:
  1. 默认类由type实例化创建。
  2. 某个类指定metaclass=MyType,那么当前类及所有派生类都由于MyType创建。
  3. 实例化对象
    - type.__init__

    - type.__call__
    - 类.__new__
    - 类.__init__

最新文章

  1. SQL行转列+动态拼接SQL
  2. css布局课件
  3. asp.net自带的异步刷新控件使用
  4. 利用ExtJS导出Excel
  5. Android Learning:数据存储方案归纳与总结
  6. Java 集合框架 ArrayList 源码剖析
  7. MergeSort 归并排序
  8. 虚拟机安装CentOS6.3及常见问题总结
  9. 正则-匹配IP地址
  10. kindeditor编辑器上传图片
  11. RocketMQ RPC
  12. K1 K2作为中断源控制红色LED灯,实现任意键按一下LED灯亮或者灭
  13. Kubernetes中的Configmap和Secret
  14. 在C#中如何判断线程当前所处的状态
  15. mysql索引优化比普通查询速度快多少
  16. bzoj3676: [Apio2014]回文串 pam
  17. POJ 1258 Agri-Net(Prim算法求解MST)
  18. javascript面向对象的一些写法
  19. java多线程实现主线程等待子线程执行完问题
  20. 欢迎使用 Flask¶

热门文章

  1. 【学习笔记】OSG中相机参数的更改
  2. 初学者可能不知道的vue技巧
  3. C# 移动开发(Xamarin.Form) Plugin.BLE 蓝牙连接
  4. RPC(Remote Procedure Call Protocol)远程过程调用协议
  5. Android(java)学习笔记158:多线程断点下载的原理(JavaSE实现)
  6. Unity查找物体的四大主流方法及区别
  7. laravel扩展包服务提供者的注册的两种方式
  8. Modal 高度 在里面css里写高 | iview
  9. this.$refs.tabs.activeKey ref就是vue里面的id
  10. k8s集群之Docker安装镜像加速器配置与k8s容器网络