python3元类简介(metaclass)
生活随笔
收集整理的這篇文章主要介紹了
python3元类简介(metaclass)
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
在Python中可以用內置函數type查看對象的類型,isinstance查看某個對象是某個類實例,通過type可以實現(xiàn)動態(tài)類,以及通過metaclass實現(xiàn)動態(tài)類
type()與isinstance()判斷對象類型
Python 3.6.4 (v3.6.4:d48eceb, Dec 19 2017, 06:54:40) [MSC v.1900 64 bit (AMD64)] Type 'copyright', 'credits' or 'license' for more information IPython 6.2.1 -- An enhanced Interactive Python. Type '?' for help.In [1]: from selectors import SelectSelectorIn [2]: type(SelectSelector) Out[2]: abc.ABCMetaIn [3]: from abc import ABCMetaIn [4]: type(ABCMeta) Out[4]: typeIn [5]: ss = SelectSelector()In [6]: type(ss) Out[6]: selectors.SelectSelectorIn [7]: from datetime import dateIn [8]: now = date.today()In [9]: type(now) Out[9]: datetime.dateIn [10]: type(date) Out[10]: typeIn [16]: isinstance(SelectSelector, ABCMeta) Out[16]: TrueIn [17]: isinstance(ABCMeta, type) Out[17]: TrueIn [18]: isinstance(ss, SelectSelector) Out[18]: True- type(object) -> the object's type 獲取對象的類型
- isinstance(obj, class_or_tuple 判斷對象是否是某一class的實例或者一組class其中一個的實例
通過上面的測試可以得出的結論
-
類的實例的類型是類,如now是date類型
-
一個類如果沒有metaclass,則該類的類型是type,(默認的),如date類的類型是type
-
一個類如果有metaclass(其基類有也可以),則該類的類型為其metaclass類,如SelectSelector類的類型為ABCMeta
-
date是type的實例,type是哪個?
-
metaclass是什么?為啥那么特殊?作用幾個?
type()實現(xiàn)動態(tài)類
type()另一個功能是動態(tài)的創(chuàng)建一個類型
>>> def fn(self, name='world'): ... print('hello %s' % name) ... >>> HH = type('Hello', (object,),dict(hello=fn)) >>> h = HH() >>> h.hello() hello worldtype()的三個參數:
1)class的名稱;
2)繼承的父類集合,注意Python支持多重繼承,如果只有一個父類,別忘了tuple的單元素寫法;
3)class的方法名稱與函數綁定,這里我們把函數fn綁定到方法名hello上。
類是一個對象
- type 可以創(chuàng)建類
- type 創(chuàng)建的對象擁有創(chuàng)建對象的能力(也就是類)
- type 就是 Python 中所有類的元類(metaclass)
metaclass
元類 并不是某一個類的名字,它是一個概念,是一種Python的思想。
python2中的用法
#!/usr/bin/env python2 # -*- coding: utf-8 -*-' Simple ORM using metaclass '__author__ = 'Michael Liao'class Field(object):def __init__(self, name, column_type):self.name = nameself.column_type = column_typedef __str__(self):return '<%s:%s>' % (self.__class__.__name__, self.name)class StringField(Field):def __init__(self, name):super(StringField, self).__init__(name, 'varchar(100)')class IntegerField(Field):def __init__(self, name):super(IntegerField, self).__init__(name, 'bigint')class ModelMetaclass(type):def __new__(cls, name, bases, attrs):if name=='Model':return type.__new__(cls, name, bases, attrs)print('Found model: %s' % name)mappings = dict()for k, v in attrs.iteritems():if isinstance(v, Field):print('Found mapping: %s ==> %s' % (k, v))mappings[k] = vfor k in mappings.iterkeys():attrs.pop(k)attrs['__mappings__'] = mappings # 保存屬性和列的映射關系attrs['__table__'] = name # 假設表名和類名一致return type.__new__(cls, name, bases, attrs)class Model(dict):__metaclass__ = ModelMetaclassdef __init__(self, **kw):super(Model, self).__init__(**kw)def __getattr__(self, key):try:return self[key]except KeyError:raise AttributeError(r"'Model' object has no attribute '%s'" % key)def __setattr__(self, key, value):self[key] = valuedef save(self):fields = []params = []args = []for k, v in self.__mappings__.iteritems():fields.append(v.name)params.append('?')args.append(getattr(self, k, None))sql = 'insert into %s (%s) values (%s)' % (self.__table__, ','.join(fields), ','.join(params))print('SQL: %s' % sql)print('ARGS: %s' % str(args))# testing code:class User(Model):id = IntegerField('uid')name = StringField('username')email = StringField('email')password = StringField('password')u = User(id=12345, name='Michael', email='test@orm.org', password='my-pwd') u.save()python3中的應用
#!/usr/bin/env python3 # -*- coding: utf-8 -*-' Simple ORM using metaclass '__author__ = 'Michael Liao'class Field(object):def __init__(self, name, column_type):self.name = nameself.column_type = column_typedef __str__(self):return '<%s:%s>' % (self.__class__.__name__, self.name)class StringField(Field):def __init__(self, name):super(StringField, self).__init__(name, 'varchar(100)')class IntegerField(Field):def __init__(self, name):super(IntegerField, self).__init__(name, 'bigint')class ModelMetaclass(type):def __new__(cls, name, bases, attrs):if name=='Model':return type.__new__(cls, name, bases, attrs)print('Found model: %s' % name)mappings = dict()for k, v in attrs.items():if isinstance(v, Field):print('Found mapping: %s ==> %s' % (k, v))mappings[k] = vfor k in mappings.keys():attrs.pop(k)attrs['__mappings__'] = mappings # 保存屬性和列的映射關系attrs['__table__'] = name # 假設表名和類名一致return type.__new__(cls, name, bases, attrs)class Model(dict, metaclass = ModelMetaclass):def __init__(self, **kw):super(Model, self).__init__(**kw)def __getattr__(self, key):try:return self[key]except KeyError:raise AttributeError(r"'Model' object has no attribute '%s'" % key)def __setattr__(self, key, value):self[key] = valuedef save(self):fields = []params = []args = []for k, v in self.__mappings__.items():fields.append(v.name)params.append('?')args.append(getattr(self, k, None))sql = 'insert into %s (%s) values (%s)' % (self.__table__, ','.join(fields), ','.join(params))print('SQL: %s' % sql)print('ARGS: %s' % str(args))# testing code:class User(Model):id = IntegerField('uid')name = StringField('username')email = StringField('email')password = StringField('password')u = User(id=12345, name='Michael', email='test@orm.org', password='my-pwd') u.save()參考
Python3 元類(metaclass)
Understanding Python metaclasses
總結
以上是生活随笔為你收集整理的python3元类简介(metaclass)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【转载保存】Mysql主从同步报错集锦
- 下一篇: websocket python爬虫_p