参考:使用元类

NOTE:

type()

1.type()函数可以用于检查一个类或者变量的类型。

#!/usr/bin/env python3

class Myclass(object):
"""docstring for Myclass"""
def __init__(self):
super(Myclass, self).__init__() def func(self):
pass def main():
h = Myclass()
print(type(h)) if __name__ == '__main__':
main()
sh-3.2# ./oop12.py
<class '__main__.Myclass'>

class的定义是运行时动态创建的,而创建class的方法就是使用type()函数。

2.因此,我们可以通过type()函数在运行时动态创建一个类,这是动态语言的一个特点:

	NewClass = type('NewClass', (Myclass,), dict(func=run))
h1 = NewClass()
h1.func()
running

创建一个对象,需要给type()函数传入三个参数:

type(name, bases, dict) -> a new class

第一个是类名,第二个是继承的基类,第三个是绑定该类中的函数。

通过type()函数创建的类完全和用class关键字声明的类一样,因为Python解释器遇到class定义的时候,也是通过type()方法来定义一个类的。

type()方法支持动态创建一个类,也就是说,动态语言本身支持运行时动态创建类,这与静态语言有非常大的不同。

metaclass

元类本身而言,它们其实是很简单的:

1)拦截类的创建

2)修改类

3)返回修改之后的类

1.元(猿)类:是我们创建类的模板。

创建一个对象时,我们需要依据它的类进行创建;创建一个类的时候,我们需要依据它的元类来进行创建。

也就是说,可以把类看成是metaclass创建出来的“实例”。

#!/usr/bin/env python3

class Listmetaclass(type):
"""docstring for Listmetaclass"""
def __new__(cls, name, bases, attrs):
attrs['add'] = lambda self, value: self.append(value)
return type.__new__(cls, name, bases, attrs) class NewClass(list, metaclass=Listmetaclass): # 指示解释器在创建类的时候通过元类的__new__()创建
pass def main():
h = NewClass()
h.add(1)
print(h) if __name__ == '__main__':
main()
sh-3.2# ./oop13.py
[1]

事实上,将函数add直接写在一个继承的子类中会好很多,这是一个十分难懂的点。

2.特殊情况:“Object Relational Mapping”,即对象-关系映射。

#!/usr/bin/env python3

class Field(object):
"""docstring for Field"""
def __init__(self, name, column_type):
super(Field, self).__init__()
self.name = name
self.column_type = column_type def __str__(self):
print('<%s:%s>' % (self.__class__.__name__, self.name)) class IntegerField(Field):
"""docstring for IntegerField"""
def __init__(self, name):
super(IntegerField, self).__init__(name, 'int') class StringField(Field):
"""docstring for StringField"""
def __init__(self, name):
super(StringField, self).__init__(name, 'string') class Modelmetaclass(type): # type
"""docstring for Modelmetaclass"""
def __new__(cls, name, bases, attrs):
if name == 'Model':
return type.__new__(cls, name, bases, attrs)
print('Found name:%s' % name)
mappings = dict() # save mappings of attributes
for i, j in attrs.items():
if isinstance(j, Field):
print('mapping: %s ==> %s' % (i, j))
mappings[i] = j # name i => 'Field'
for i in mappings.keys():
attrs.pop(i) # delete attrs that have been transfer to 'Field'
attrs['__mappings__'] = mappings
attrs['__table__'] = name
return type.__new__(cls, name, bases, attrs) class Model(dict, metaclass=Modelmetaclass):
"""docstring for Model"""
# reuse the old definitions of functions
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] = value def 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)) # User provide the interfaces
class User(Model):
id = IntegerField('id')
name = StringField('username')
email = StringField('email')
password = StringField('password') def main():
# Create an object
u = User(id=9, name='Wasdns', email='952693358@qq.com', password='1234567')
# Save the object in the Database
u.save() if __name__ == '__main__':
main()

具体解释请参考原文“美3333333”的回答。

2017.3.10

Python学习札记(四十) 面向对象编程 Object Oriented Program 11的更多相关文章

  1. Python学习札记(三十) 面向对象编程 Object Oriented Program 1

    参考:OOP NOTE 1.面向对象编程--Object Oriented Programming,简称OOP,是一种程序设计思想.OOP把对象作为程序的基本单元,一个对象包含了数据和操作数据的函数. ...

  2. Python学习札记(三十七) 面向对象编程 Object Oriented Program 8 @property

    参考:@property NOTE 1.在绑定参数时,为了避免对属性不符合逻辑的操作,需要对传入的参数进行审核. #!/usr/bin/env python3 class MyClass(object ...

  3. Python学习札记(三十三) 面向对象编程 Object Oriented Program 4

    参考:继承和多态 NOTE 著名的开闭原则: 对扩展开放:允许新增Animal子类: 对修改封闭:不需要修改依赖Animal类型的Animal_func()等函数. 1.eg. #!/usr/bin/ ...

  4. Python学习札记(三十一) 面向对象编程 Object Oriented Program 2

    参考:类和实例 注意理解第七点. NOTE: 1.类是抽象的模板,比如Student类,实例是根据类创建出来的一个个具体的"对象",每个对象都拥有相同的方法,但各自的数据可能不同. ...

  5. Python学习札记(三十四) 面向对象编程 Object Oriented Program 5

    参考:获取对象信息 NOTE 1.type()函数可以用来判断对象的类型: >>> type(123) <class 'int'> >>> type(' ...

  6. Python学习札记(三十八) 面向对象编程 Object Oriented Program 9

    参考:多重继承 NOTE #!/usr/bin/env python3 class Animal(object): def __init__(self, name): self.name = name ...

  7. Python学习札记(三十六) 面向对象编程 Object Oriented Program 7 __slots__

    参考:slots NOTE 1.动态语言灵活绑定属性及方法. #!/usr/bin/env python3 class MyClass(object): def __init__(self): pas ...

  8. Python学习札记(三十五) 面向对象编程 Object Oriented Program 6

    参考:实例属性和类属性 NOTE Python是动态语言,根据类创建的实例可以任意绑定属性. class Student(object): def __init__(self, name): self ...

  9. Python学习札记(三十二) 面向对象编程 Object Oriented Program 3

    参考:访问限制 NOTE 1.eg. #!/usr/bin/env python3 class Student(object): """docstring for Stu ...

随机推荐

  1. [Bootstrap] install Bootstrap framework in window 7 by npm

    Install with npm You can also install Bootstrap using npm: $ npm install bootstrap require('bootstra ...

  2. javaWeb中的文件上传下载

    在Web应用系统开发中,文件上传和下载功能是非常常用的功能,今天来讲一下JavaWeb中的文件上传和下载功能的实现. 对于文件上传,浏览器在上传的过程中是将文件以流的形式提交到服务器端的,如果直接使用 ...

  3. 微信小程序 --- 获取当前坐标

    获取位置:get.location type:wgs84(是全球定位系统,获取的坐标,gcj02是国家测绘局给出的坐标) btnclick:function(){ wx.getLocation({ t ...

  4. onethink封装arclist调用文章列表!

    其实没有什么东西,做个记录,方便以后使用! <ul> <arclist mid='2' cid='2' row='2'> <li>{$title}</li&g ...

  5. 【css预处理器】------css预处理器及sass基本介绍------【巷子】

    001.什么是css预处理器? css预处理器定义了一种新的语言.用一种专门的编程语言,为css增加了一些编程的特性,将css作为目标生成文件,然后开发者就只要使用这种语言进行编码工作.(通俗点说“” ...

  6. 170614、MySQL存储引擎-MyISAM与InnoDB区别

    MyISAM 和InnoDB 讲解 InnoDB和MyISAM是许多人在使用MySQL时最常用的两个表类型,这两个表类型各有优劣,视具体应用而定.基本的差别为:MyISAM类型不支持事务处理等高级处理 ...

  7. oracle之用户名密码包含特殊字符时候怎么使用sqlplus登录

    oracle有时候用户密码包含一些特殊字符直接登录会报错,需要使用以下方式登录sqlplus sqlplus 'username/"password"' PS:整体使用单引号括起来 ...

  8. centos linux系统日常管理3 服务管理ntsysv,chkconfig,系统日志rsyslog,last ,lastb ,exec,xargs,dmesg,screen,nohup,curl,ping ,telnet,traceroute ,dig ,nc,nmap,host,nethogs 第十六节课

    centos linux系统日常管理3  服务管理ntsysv,chkconfig,系统日志rsyslog,last ,lastb ,exec,xargs,dmesg,screen,nohup,cur ...

  9. 【开发者笔记】python

    题记: 最近做Python导入接口,用到xlrd包读取excel文件信息入库,获取合并单元格信息时遇到时而成功时而失败的情况,一开始用xls文件读取不了合并单元格信息,后来换用xlsx格式可以读取.但 ...

  10. vuejs和webpack项目(VueComponent)初尝试——瀑布流组件

    碎碎念:     好久不见,最近自己有些懈怠没更过多少博,主要原因之一是对自己学习方式的一些思考,翻看之前的博客多是记录学习笔记这反映出了自己对于前端还停留在学习-复习知识点的阶段压根没多少实践经验啊 ...