python3元类简介(metaclass)
在Python中可以用內(nèi)置函數(shù)type查看對(duì)象的類(lèi)型,isinstance查看某個(gè)對(duì)象是某個(gè)類(lèi)實(shí)例,通過(guò)type可以實(shí)現(xiàn)動(dòng)態(tài)類(lèi),以及通過(guò)metaclass實(shí)現(xiàn)動(dòng)態(tài)類(lèi)
type()與isinstance()判斷對(duì)象類(lèi)型
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 獲取對(duì)象的類(lèi)型
- isinstance(obj, class_or_tuple 判斷對(duì)象是否是某一class的實(shí)例或者一組class其中一個(gè)的實(shí)例
通過(guò)上面的測(cè)試可以得出的結(jié)論
-
類(lèi)的實(shí)例的類(lèi)型是類(lèi),如now是date類(lèi)型
-
一個(gè)類(lèi)如果沒(méi)有metaclass,則該類(lèi)的類(lèi)型是type,(默認(rèn)的),如date類(lèi)的類(lèi)型是type
-
一個(gè)類(lèi)如果有metaclass(其基類(lèi)有也可以),則該類(lèi)的類(lèi)型為其metaclass類(lèi),如SelectSelector類(lèi)的類(lèi)型為ABCMeta
-
date是type的實(shí)例,type是哪個(gè)?
-
metaclass是什么?為啥那么特殊?作用幾個(gè)?
type()實(shí)現(xiàn)動(dòng)態(tài)類(lèi)
type()另一個(gè)功能是動(dòng)態(tài)的創(chuàng)建一個(gè)類(lèi)型
>>> def fn(self, name='world'): ... print('hello %s' % name) ... >>> HH = type('Hello', (object,),dict(hello=fn)) >>> h = HH() >>> h.hello() hello worldtype()的三個(gè)參數(shù):
1)class的名稱(chēng);
2)繼承的父類(lèi)集合,注意Python支持多重繼承,如果只有一個(gè)父類(lèi),別忘了tuple的單元素寫(xiě)法;
3)class的方法名稱(chēng)與函數(shù)綁定,這里我們把函數(shù)fn綁定到方法名hello上。
類(lèi)是一個(gè)對(duì)象
- type 可以創(chuàng)建類(lèi)
- type 創(chuàng)建的對(duì)象擁有創(chuàng)建對(duì)象的能力(也就是類(lèi))
- type 就是 Python 中所有類(lèi)的元類(lèi)(metaclass)
metaclass
元類(lèi) 并不是某一個(gè)類(lèi)的名字,它是一個(gè)概念,是一種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 # 保存屬性和列的映射關(guān)系attrs['__table__'] = name # 假設(shè)表名和類(lèi)名一致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中的應(yīng)用
#!/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 # 保存屬性和列的映射關(guān)系attrs['__table__'] = name # 假設(shè)表名和類(lèi)名一致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 元類(lèi)(metaclass)
Understanding Python metaclasses
總結(jié)
以上是生活随笔為你收集整理的python3元类简介(metaclass)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 【转载保存】Mysql主从同步报错集锦
- 下一篇: 爬虫遇到路径转换的解决方案